- 關(guān)于 jwt 的原理及概念可以自行在網(wǎng)絡(luò)上搜索了解一下,這里推薦一篇寫的比較好的博客
另附 JWT 的官方文檔: https://jwt.io/introduction/
python 對于 jwt 的實現(xiàn), 目前已經(jīng)存在了一些第三方的庫, 相信學(xué)習(xí)過 python 的程序猿都知道 itsdangerous 這個庫了, 它的底層原理就是基于 jwt 進行實現(xiàn)的
python實現(xiàn)生成 json web token
環(huán)境: python3.6.7
依賴包: jwt, time
1)JWT 的簽名算法有三種旗笔。
1.對稱加密HMAC【哈希消息驗證碼】 HS256/HS384/HS512
這種加密方式?jīng)]有公鑰,私鑰之分, 也就是只有一個密鑰, 這種加密方式適用于: 服務(wù)器將生成的jwt發(fā)送給接收方, 接收方將其返回給服務(wù)器, 服務(wù)器解析 jwt, 完成身份驗證.
2.非對稱加密RSASSA【RSA簽名算法】RS256/RS384/RS512
3.ECDSA【橢圓曲線數(shù)據(jù)簽名算法】 ES256/ES384/ES512
2).對稱加密HMAC 生成 jwt
import time
import jwt
# payload
token_dict = {
'iat':time.time(), # 時間戳
'name':'George'
}
"""payload 中一些固定參數(shù)名稱的意義, 同時可以在payload中自定義參數(shù)"""
# iss 【issuer】發(fā)布者的url地址
# sub 【subject】該JWT所面向的用戶纱昧,用于處理特定應(yīng)用桶雀,不是常用的字段
# aud 【audience】接受者的url地址
# exp 【expiration】 該jwt銷毀的時間槐脏;unix時間戳
# nbf 【not before】 該jwt的使用時間不能早于該時間衷旅;unix時間戳
# iat 【issued at】 該jwt的發(fā)布時間澜驮;unix 時間戳
# jti 【JWT ID】 該jwt的唯一ID編號
# headers
headers = {
'alg': "HS256", # 所使用的加密算法方式
'kid': "8888", # key_id
}
"""headers 中一些固定參數(shù)名稱的意義"""
# jku: 發(fā)送JWK的地址漱逸;最好用HTTPS來傳輸
# jwk: 就是之前說的JWK
# kid: jwk的ID編號
# x5u: 指向一組X509公共證書的URL
# x5c: X509證書鏈
# x5t:X509證書的SHA-1指紋
# x5t#S256: X509證書的SHA-256指紋
# typ: 在原本未加密的JWT的基礎(chǔ)上增加了 JOSE 和 JOSE+ JSON纳决。JOSE序列化后文會說及释树。適用于JOSE標(biāo)頭的對象與此JWT混合的情況肠槽。
# crit: 字符串?dāng)?shù)組,包含聲明的名稱奢啥,用作實現(xiàn)定義的擴展秸仙,必須由 this->JWT的解析器處理。不常見桩盲。
# 調(diào)用jwt庫,生成json web token
jwt_token = jwt.encode(token_dict, # payload, 有效載體
"George8888", # 進行加密簽名的密鑰
algorithm="HS256", # 指明簽名算法方式, 默認也是HS256
headers=headers # json web token 數(shù)據(jù)結(jié)構(gòu)包含兩部分, payload(有效載體), headers(標(biāo)頭)
).decode('ascii') # python3 編碼后得到 bytes, 再進行解碼(指明解碼的格式), 得到一個str
print(jwt_token)
# 個人測試生成結(jié)果如下: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ijg4ODgifQ.eyJpYXQiOjE1NjQwMjU0MTcuNTc1NDQ3LCJuYW1lIjoiR2VvcmdlIn0.ScPOppgmV3wM-o8ohVL4u2mUGPql5-cwaOO8ZvLn4jM
- 使用 python 對 jwt 進行解析
import jwt
# 將上面生成的 jwt 進行解析認證
jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ijg4ODgifQ.eyJpYXQiOjE1NjQwMjU0MTcuNTc1NDQ3LCJuYW1lIjoiR2VvcmdlIn0.ScPOppgmV3wM-o8ohVL4u2mUGPql5-cwaOO8ZvLn4jM"
data = None
try:# 需要解析的 jwt 密鑰 使用和加密時相同的算法
data = jwt.decode(jwt_token, "George8888", algorithms=['HS256'])
except Exception as e:# 如果 jwt 被篡改過; 或者算法不正確; 如果設(shè)置有效時間, 過了有效期; 或者密鑰不相同; 都會拋出相應(yīng)的異常
print(e)
# 解析出來的就是 payload 內(nèi)的數(shù)據(jù)
print(data)
# 輸出: {'iat': 1564025417.575447, 'name': 'George'}
4)如果是使用私鑰公鑰進行加密解密的方式(由請求方使用私鑰進行加密生成 jwt, 接收方使用公鑰解密), 只需要將相應(yīng)參數(shù)更換成私鑰(將私鑰證書讀取出來, 賦值給相應(yīng)參數(shù)即可), 并使用雙方約定好的的簽名算法
- python 對于 jwt 的實現(xiàn), 已經(jīng)有了 itsdangerous 這個庫做了很好的支撐, 使用起來還是很方便的, 大家可以自行去了解一下.
itsdangerous 官方文檔: https://itsdangerous.readthedocs.io/en/1.1.x/