一、基於JWT的Token登錄認證 1. JWT簡介 json Web Token(縮寫JWT)是目前最流行的跨域認證解決方案 session登錄的認證方案是看,用戶從客戶端傳遞用戶名和密碼登錄信息,服務端認證後將信息儲存在session中,將session_id放入cookie中,以後訪問其他頁面 ...
一、基於JWT的Token登錄認證
1. JWT簡介
json Web Token(縮寫JWT)是目前最流行的跨域認證解決方案
session登錄的認證方案是看,用戶從客戶端傳遞用戶名和密碼登錄信息,服務端認證後將信息儲存在session中,將session_id放入cookie中,以後訪問其他頁面,伺服器都會帶著cookie,服務端會自動從cookie中獲取session_id,在從session中獲取認證信息。
JWT的解決方案是,將認證信息返回個客戶端,儲存在客戶端,下次訪問其他頁面,需要從客戶端傳遞認證信息回伺服器端。
2. JWT原理
JWT原理就是,伺服器認證後,生成一個json格式的對象 ,發送個客戶端,
{
"用戶名": "admin",
"角色": "超級管理員",
"到期時間": "2019-07-13 00:00:00"
}
以後,客戶端域伺服器通信的時候,都要發回這個json對象,伺服器完全靠這個對象認定用戶身份,(但肯定不會像上面那樣,那麼簡單的發送一個對象)這樣的話,session中就沒有數據了,後面更容易實現擴展
3. JWT的數據結構
JWT分為三個部分,header(頭部) payload (負載) signature (簽名)
一個完整的JWT數據是這樣的
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjNmMmc1N2E5MmFhIn0.
eyJpYXQiOjE1NjI4MzM0MDgsImlzcyI6Imh0dHA6XC9cL3d3dy5weWcuY29tIiwiYXVkIjoiaHR0cDpcL1wvd3d3LnB5Zy5jb20iLCJuYmYiOjE1NjI4MzM0MDcsImV4cCI6MTU2MjkxOTgwOCwianRpIjoiM2YyZzU3YTkyYWEiLCJ1c2VyX2lkIjoxfQ.
NFq1qQ-Z5c4pwit8ZkyWEwX6SBXmnHJcc6ZDgSD5nhU
中間是有三個點的,分別就是 頭部 負載 和簽名 (點在每一行的最後)
3.1 頭部 是一個json對象 作用是描述JWT元數據,一般是這樣的
{
"alg": "HS256", //表示簽名的演算法預設是 HMAC SHA256(寫成 HS256)
"typ": "JWT" //表示這個令牌(token)的類型(type),JWT 令牌統一寫為JWT
}
最後,將上面的 JSON 對象使用 Base64URL 演算法(詳見後文)轉成字元串。
3.2 負載 也是一個 JSON 對象 ,用來存放實際需要傳遞的數據。JWT 規定了7個官方欄位,供選用
除了官方欄位,你還可以在這個部分定義私有欄位
這個 JSON 對象也要使用 Base64URL 演算法轉成字元串(防止除了用戶的人看見嘛)。
註意:JWT 預設是不加密的,任何人都可以讀到,所以不要把秘密信息放在這個部分。(雖然加密了,防止解密的壞人解密後修改在加密)
3.3 簽名 是對前兩部分的簽名(可以理解成在加密一份),防止數據篡改。
首先,需要指定一個密鑰(自己設置),這個密鑰只有伺服器才知道,不能泄露給用戶。
使用 Header 裡面指定的簽名演算法(預設是 HMAC SHA256)產生簽名
如:HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret) //使用Header 裡面指定的簽名演算法 將頭部和負載部用逗號拼接起來,在加上自己設置的秘鑰
那麼簽名就出來的。
簽名出來後,現在有了 頭部的字元串,和負載的字元串 ,還有簽名的,在將這三個字元串用 . 拼接出來,就可以將這個拼接好的字元串,返回給客戶端的
JWT數據就返回得了客戶端,需要註意的是,頭部和負載部,是用base64URL轉成字元串的,簽名是用頭部指定的演算法轉成字元串的 不用弄混掉
4. JWT 的使用方式
客戶端,接受到了伺服器返回的jwt,可以儲存到cookie中,也可以儲存在 localStorage。
此後,客戶端每次與伺服器通信,都要帶上這個 JWT。你可以把它放在 Cookie 裡面自動發送,但是這樣不能跨域,所以更好的做法是放在 HTTP 請求的頭信息Authorization
欄位裡面。
一旦我們使用的JWT,JWT的類別人封裝好的,會自動將生成的token放入響應頭中去,然後再次去訪問頁面的時候會帶著響應回來token去訪問頁面
JWT在請求頭中發送,如:會多了個請求頭
Authorization: Bearer <token>
然後,在伺服器中,需要驗證這個token,是否有效
二、Django---使用jwt中的token鑒權機制完成狀態保持的步驟
1. 安裝包 djangorestframework-jwt
pip install djangorestframework-jwt
2. 配置drf, jwt過期時間
REST_FRAMEWORK = {
''''''
# 身份認證的方式:JWT session
'DEFAULT_AUTHENTICATION_CLASSES': (
# 前後端分離使用jwt驗證
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
# 訪問admin後臺使用session
'rest_framework.authentication.SessionAuthentication',
),
}
# 過期時間為10小時
JWT_AUTH = {
# timedelta 時間差
'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=10),
}
3. 在創建use對象的時候手動生成token
# 需要生成token
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) # header.payload.signature
4. 在序列化中定義只輸出的token屬性
token = serializers.CharField(read_only=True)
5. 為user添加token屬性才能輸出到客戶端
user.token = token