一、基于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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/114476.html
標籤:Python
