5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Django Rest FrameworkでJWT認証を実装する方法について

Posted at

前提

  • カスタムユーザを作成済み
  • テスト用データを作成済み

今回はカスタムユーザModelを作成して、employee_numberとpasswordでトークンを作成します
カスタムユーザを作成されたい方は以下の記事を参考にしてください

テスト用データを作成する際はfixtureを使うと効果的です
fixtureを作成されたい方は以下の記事を参考にしてください

認証の種類

Webで使われている主な認証方法は以下の通りです

  • Basic
  • Token
  • Json Web Token(JWT)
  • Session

今回はJWT認証について具体例を交えながら解説していきます

Json Web Token(JWT)認証

認証方法の一つでJSONベースのデータを暗号化してつくられる一意のトークンを使用して認証します
通常のToken認証との違ってクライアント側でTokenの正当性を確認できます
JWTから直接ユーザーを特定できるため、トークンをデータベースに保存しない(する必要がない)のが大きな特徴です
また、通常のToken認証のToken自体には意味を持たないのに対し、JWTはそれ自体が情報を持ちます
そのため、JWTの内部にパスワードなどの個人情報などを含めることは推奨されません

JWTの構成

上から順に

  • ヘッダ
  • ペイロード
  • キー(署名)

の3つで構成されています

ヘッダ

ヘッダには

  • トークンの種類(JWT)
  • 使用されている暗号方式(HMAC, SHA256, RSA)

の2つで構成されており、以下のような見た目になっています

{
    "alg": "HS256",
    "typ": "JWT"
}

algは署名に使っているアルゴリズムを表しています
typはトークンの種別(Json Web Token)を表しています

ペイロード

データ本体のことを指します
また、ペイロード内にはClaimというデータの属性情報も記載することができ、

  • registered
  • public
  • private

の3種類あります

registered

必須ではないですがペイロード内に記載することが推奨されています
一般的によく使用されるものとして挙げられるのは

  • iss(issuer,発行者)
  • exp(expiration time,有効期限)
  • sub(subject,対象者)
  • aud(audience,視聴者)

などです

IANA(Internet Assigned Numbers Authority)のサイトから使用できるClaimの一覧を確認できます

public

IANAですでに定義されていないものであればJWTを使用する者が自由に定義することができます

private

当事者間でJWTを使って情報を共有するために作成される独自のClaimでregisterdでもpublicでもありません

ペイロード例

よくある例としては以下のようにデータとsubというregistered claimを組み合わせたペイロードがあります

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

前述の通りJWTの内部にパスワードなどの個人情報などを含めることは推奨されません
そのため、ペイロード内にパスワードなどの秘匿情報を入れることはありません

キー(署名)

キー(署名)は

  • エンコードされたヘッダー
  • エンコードされたペイロード
  • 秘密鍵

の3つを組み合わせて、ヘッダーで指定した暗号方式でエンコードします

例えば、HMACSHA256をヘッダに指定した場合、キー(署名)を以下のように作成します

HMACSHA256(
  # エンコードされたヘッダ
  base64UrlEncode(header) + "." +
  # エンコードされたペイロード
  base64UrlEncode(payload),
  # 秘密鍵
  secret)

secretには主にDjangoのsecretkeyが利用されています

Django Rest Frameworkで再現してみよう!

Django Rest FrameworkでJWT認証を設定するには以下のファイルを編集します

  • settings.py
  • プロジェクトのurls.py

settings.py

今回は公式が推奨しているSimple JWTを使用します

まず、Simple JWTをインストールします

pip install djangorestframework-simplejwt

インストールが終わった後にsettings.pyに以下を追加します

settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
}

プロジェクトのurls.py

以下のコードを追加します

プロジェクトのurls.py
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    ...
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    ...
]

tokenを発行してみよう!

以下に

  • employee_number
  • password

を入力してPOSTします
スクリーンショット 2022-12-24 15.05.17.png

すると、トークンが発行されます
スクリーンショット 2022-12-24 15.05.49.png

右にあるAuthorizeボタンを押します
スクリーンショット 2022-12-18 20.48.06.png

先ほど作成したaccessトークンを入力し、Authorizeボタンを押すと認証完了です
スクリーンショット 2022-12-24 15.15.01.png

エンドポイントを操作できるようになりました
スクリーンショット 2022-12-17 12.04.37.png
以上です

記事の紹介

以下の記事も書いたので良かったら読んでみてください

参考

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?