JWT
- 什麼是JWT??
- JWT是指
一般用于使用者認證,常用有(api,小程式,前後端分離)的項目json web token
- JWT是指
- jwt 原理請求圖
JWT原理與使用 - 基于傳統的token認證
- 使用者登入,服務端傳回token給使用者,并儲存token。
- 當使用者再次通路時,攜帶token發起請求,服務端,查詢資料庫,對比token,token正确認證通過
- 基于JWT token認證
- 使用者登入,服務端傳回token(服務端不儲存)給使用者。
- 當使用者再次通路時,攜帶token發起請求,服務端拿到token後,再做token檢驗。
- 優勢:相比于傳統,它token不用儲存,減小資料庫的查詢,減小伺服器的壓力。
JWT 實作過程
使用者登入成功,使用 jwt
建立一個 token
并傳回給使用者
jwt
token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
注意:jwt 生成的token是由三段字元串組成的,并由
.
連接配接而成的
- 第一段字元串,
,内部包含算法和token類型。HEADER
{
“alg”: “HS256”,
“typ”: “JWT”
}
通過json轉化成字元串,然後通過
base64url
加密而成
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
- 第二段字元串,
,内部是自定義值PAYLOAD
{
“phone”: “1234567890”,
“name”: “name”,
“exp”: “12” # 逾時時間
}
通過json轉化成字元串,然後通過
base64url
加密而成
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
- 第三段字元串:
- 第一步:把第一、第二段密文拼接起來
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
- 第二步:把第一步拼接起來的密文進行
加密HS256 + 加鹽
- 第三步:對
加密後的密文,再進行HS256
加密base64url
- 第一步:把第一、第二段密文拼接起來
當使用者再次通路時,需要攜帶token,後端需要進行token檢驗
- 擷取token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5ceyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
- 第一步:切割token
- 第二步:對第二段密文進行
解密,并擷取base64url
資訊檢測token是否已經失效payload
{
“phone”: “1234567890”,
“name”: “name”,
“exp”: “12” # 逾時時間
}
- 第三步:把第一、第二段密文拼接起來,進行
加密HS256 + 加鹽
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
密文 =base64url
解密(使用者帶來的token中的第三段:SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c)
如果相等,則說明token未被修改過,認證通過。
Python 實作過程
-
pip install pyjwt
import jwt
import datetime
from jwt import exceptions
# 鹽值
SALT = safa
def create_token():
# 構造header
headers = {
'typ': 'jwt',
'alg': 'HS256'
}
# 構造payload
payload = {
'user_id': 1, # 自定義使用者ID
'username': 'name', # 自定義使用者名
'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=5) # 逾時時間
}
result = jwt.encode(payload=payload, key=SALT, algorithm="HS256", headers=headers).decode('utf-8')
return result
def get_payload(token):
"""
根據token擷取payload
:param token:
:return:
"""
try:
verified_payload = jwt.decode(token, SALT, True)
return verified_payload
except exceptions.ExpiredSignatureError:
print('token已失效')
except jwt.DecodeError:
print('token認證失敗')
except jwt.InvalidTokenError:
print('非法的token')
if __name__ == '__main__':
# jwt 生成token
token = create_token()
# jwt 檢驗token
payload = get_payload(token)