前提
- カスタムユーザを作成済み
- テスト用データを作成済み
今回はカスタムユーザ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に以下を追加します
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
}
プロジェクトの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
先ほど作成したaccessトークンを入力し、Authorize
ボタンを押すと認証完了です
記事の紹介
以下の記事も書いたので良かったら読んでみてください
参考