JWT簡介
Json web token (JWT), 是爲了在網絡應用間傳遞聲明的基於JSON的開放標準,該token被設計爲緊湊且安全的,特別適用於分佈式站點的單點登錄(SSO)場景。其中的分佈式站點的單點登陸的狀態保持,在這裏簡單介紹下:舉京東的例子,主頁www.jd.com作爲一個站點部署在單獨的服務器上,其購物車www.car.jd.com作爲單獨的一個站點部署在單獨的服務器上。那麼單點登陸,意思就是在這兩個站點中的任意一個完成登陸之後,在另外的一個站點也會完成狀態保持,就是單點登陸。好了言歸正傳介紹JWT。
JWT在實現狀態保持上有着得天的優勢:1>json的通用性,所以JWT是可以進行跨語言支持的 2>jwt的構成非常簡單,字節佔用很小,便於傳輸 3>擴展性好不需要在服務端保存會話信息
傳統的狀態保持實現方法
session
http協議本身是一種無狀態的協議,如果需要實現用戶狀態保持,我們通常使用session,將用戶信息存儲在服務端,並把session的key響應給瀏覽器的cookie中,用戶下一次再來訪問我們的時候帶上cookie我們就可以對其實現狀態保持。這樣做的缺點很多:1>當用戶量很大的時候我們需要在服務端緩存大量的session信息,如果緩存在服務器的內存中,服務端開銷會變大,甚至會出現嚴重的後果2>cookie在瀏覽器中用戶可以選擇禁用的,我們就無法實現狀態保持3>擴展性不好,session是保存在服務器的內存中的,當有多個站點的時候就無法實現多站點的任意單點狀態保持。
DRF中實現JWT
安裝和配置
# 安裝相應的模塊
pip install djangorestframework-jwt
# 配置settings文件
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':(
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
}
JWT_AUTH = {
# 配置jwt簽發有效期
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
}
封裝使用
# 將方法封裝到項目的utils中,創建jwt_token.py
from rest_framework_jwt.settings import api_settings
def get_jwt_token(user):
# JWT做狀態保持的時機是:用戶註冊成功之後,返回結果之前
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
# 當前的註冊用戶對象
payload = jwt_payload_handler(user)
# JWT token
token = jwt_encode_handler(payload)
return token
調用
在需要使用的位置直接調用utils中的get_jwt_token(user)方法,需要將user對象傳入到方法中,得到的返回值就是token,可以直接放在Response中直接簽發。
# 例1
# 用戶註冊成功之後,創建新用戶返回響應之前,做狀態保持
from ..utils.jwt_token import get_jwt_token
def create(self, validated_data):
user = super().create(validated_data)
user.set_password(password)
user.save()
# 調用get_jwt_token方法
token = get_jwt_token(user)
# 將token字段添加到user對象中,做響應
user.token = token
return user
服務端開啓jwt驗證
使用的就是settings文件中配置的自定義的用戶認證。
前端需要在每次請求的時候將token放在headers中攜帶上。