django 這邊需要使用 Django REST framework (drf) 及 drf 官方推薦實作 JWT 的 Django-rest-framework-simplejwt
這兩個套件。
pip install djangorestframework djangorestframework_simplejwt
再來設定 django 的 back_end/settings.py
引入,首先來設定 INSTALLED_APPS
,將 rest_framework
和 rest_framework_simplejwt.token_blacklist
引入
INSTALLED_APPS = [
'rest_framework',
'rest_framework_simplejwt.token_blacklist'
]
加入這段 REST_FRAMEWORK
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
再來要把 JWT 的設定改成自己喜歡的樣子,先引入 timedelta
from datetime import timedelta
設定 ACCESS_TOKEN_LIFETIME
時效比較短, REFRESH_TOKEN_LIFETIME
時效比較長,原則上是看你想要 user 維持登入時間多久,不過接下來設定 ROTATE_REFRESH_TOKENS 等於 True,官方預設更新 token 的時候,只更新 access token,只回傳 access token,所以使用者最多只能維持登入 30 天,這邊改成 True,會連 refresh token 一起更新,之後每次 refresh , server 都會回傳一組 access 和 refresh token 給前台,再配合 BLACKLIST_AFTER_ROTATION 為 True,會讓 token 刷新之後,舊的 refresh 和 access token 都失去權限,這樣別人就不能舊的 refresh token 去獲得新的 token,會更加安全。詳細內容可以看一下官方的 settings 說明。
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=30),
'ROTATE_REFRESH_TOKENS': True,
'BLACKLIST_AFTER_ROTATION': True,
'UPDATE_LAST_LOGIN': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'JWK_URL': None,
'LEEWAY': 0,
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}
我們先來做一個用來做驗證相關的 module
python manage.py startapp authentication
加入 app
INSTALLED_APPS = [
'authentication'
]
加入 url
urlpatterns = [
path('api/',include('authentication.urls'))
]
新增 urls.py
到 back_end/authentication
,refresh 和 verify 功能我們用 simple jwt
內建的方法
# back_end/authentication/urls.py
from django.urls import path
from . import views
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
TokenVerifyView
)
urlpatterns = [
# JWT ###################################
path('token/', views.MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('token/verify/', TokenVerifyView.as_view(), name='token_verify'),
]
至於獲取 token,如果在前台解析 token,可以獲得一些 payload 資訊,不過預設只有這些簡單的資訊,至少回個 username 吧!不然超難用的誒
所以我們來 back_end/authentication/views.py
來客製化我們獲取 token 的方法,這裡我們多加入 username 資訊,這裡基本上就是照抄官方 document 的客製化方法
from django.shortcuts import render
# Create your views here.
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
# Add custom claims
token['username'] = user.username
return token
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
後端基本上到這裡,下一篇來講前端該怎麼搞。