JWT概念:
Json web token (JWT), 是爲了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519).該token被設計爲緊湊且安全的,特別適用於分佈式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。
基於token的鑑權機制
token由3部分組成
-
jwt的頭部承載兩部分信息:
聲明類型,這裏是jwt
聲明加密的算法 通常直接使用 HMAC SHA256
對頭部進行base64加密,構成第一部分 -
payload
載荷就是存放有效信息的地方。這個名字像是特指飛機上承載的貨品,這些有效信息包含三個部分
標準中註冊的聲明
公共的聲明
私有的聲明公共的聲明 : 公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息.但不建議添加敏感信息,因爲該部分在客戶端可解密.
私有的聲明 : 私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因爲base64是對稱解密的,意味着該部分信息可以歸類爲明文信息。
-
signature
JWT的第三部分是一個簽證信息,這個簽證信息由三部分組成:
header (base64後的)
payload (base64後的)
secret
這個部分需要base64加密後的header和base64加密後的payload使用.連接組成的字符串,然後通過header中聲明的加密方式進行加鹽secret組合加密,然後就構成了jwt的第三部分。注意:secret是保存在服務器端的,jwt的簽發生成也是在服務器端的,secret就是用來進行jwt的簽發和jwt的驗證
token作爲保存狀態的一種方式,原理流程如圖
1.用戶註冊或登錄時使用用戶名和密碼來請求服務器
2 服務器驗證用戶名密碼無誤後,經過加密算法構造出一個token值
3 服務器將生成的token值簽發給用戶,客戶端會存儲這個token值
4 客戶端每次發起請求登錄服務器時,都會攜帶token值,服務器會拿到客戶端請求頭裏的header和payload再次進行計算得出token兩者進行比較來判斷是否原用戶
優點:
因爲json的通用性,所以JWT是可以進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用。
因爲有了payload部分,所以JWT可以在自身存儲一些其他業務邏輯所必要的非敏感信息。
便於傳輸,jwt的構成非常簡單,字節佔用很小,所以它是非常便於傳輸的。
它不需要在服務端保存會話信息, 所以它易於應用的擴展
WTF在DRF框架中的使用:
- 虛擬環境中安裝
pip install djangorestframework-jwt
- 配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), # 有效期
}
- 使用
Django REST framework JWT 擴展的說明文檔中提供了手動簽發JWT的方法
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
簽發的token值可以作爲用戶對象的一個屬性,進行序列化輸出給客戶端用戶
user.token = token