Json web token (JWT),是爲了在網絡應用環境間傳遞聲明而執行的一種基於 JSON 的開放標準(RFC 7519).該 token 被設計爲緊湊且安全的,特別適用於分佈式站點的單點登陸(SSO)場景。JWT 的聲明通常被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也能夠增長一些額外的其它業務邏輯所必須的聲明信息,該 token 也可直接被用於認證,也可被加密。python
HTTP 是一個無狀態的應用層協議。web
比如咱們在淘寶上網購:redis
然而,由於 HTTP 是無狀態的,咱們在下單購買的時候,服務器此時已經不記得咱們的身份信息了,須要從新進行身份認證。算法
傳統的登陸校驗採用的是 cookie-seession 方式,它的流程通常以下:django
傳統模式的缺點是可擴展性差。對於單機操做影響不大,但若是是服務器集羣,或者是跨域的服務導向架構,就要求 session 數據共享,每臺服務器都可以讀取 session,而 session 通常是採用文件的方式存儲,這會帶來文件同步問題和文件讀取問題。即使將 session 放入到 redis 中,也沒法避免高併發數據的讀取問題。json
JWT 採用的是 token 令牌的方式進行校驗:後端
這樣作的優勢在於:api
一個 JWT 字符串包括如下三個部分:跨域
頭部(header)緩存
標識用於生成簽名的算法,例如:
{ ‘typ‘: ‘JWT‘, ‘alg‘: ‘HS256‘ }
typ 表示 token 的類型,默認爲 JWT,通常不改動。
alg 表示加密算法,默認 HMAC SHA256。
載荷(payload)
簽證(signature)
咱們的項目後端是基於 Django 進行開發的。
通常而言是在 restful 的接口中使用 JWT token,相關的 Django 庫是 djangorestframework
和 djangorestframework-jwt
。
首先須要在 settings
中設置 DEFAULT_AUTHENTICATION_CLASSES
來進行用戶認證:
REST_FRAMEWORK = { 'DEFAULT_SCHEMA_CLASS': ( 'rest_framework.schemas.coreapi.AutoSchema' ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.BasicAuthentication', ) }
接着設置 JWT_AUTH 來進行 token 的刷新:
JWT_AUTH = { 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), 'JWT_ALLOW_REFRESH': True, 'JWT_AUTH_HEADER_PREFIX': 'JWT', }
在用戶登陸時,生成 token:
serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = self.perform_create(serializer) re_dict = serializer.data payload = jwt_payload_handler(user) re_dict['token'] = jwt_encode_handler(payload) re_dict['username'] = user.username headers = self.get_success_headers(serializer.data) return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers)
在 urls
中註冊路由:
urlpatterns = [ path('login/', obtain_jwt_token), path('refresh/', refresh_jwt_token), path('verify/', verify_jwt_token), ]