Python 生成 JWT(json web token) 及 解析方式


一.關於 jwt 的原理及概念可以自行在網絡上搜索了解一下,這里推薦一篇寫的比較好的博客

  深入了解Json Web Token之概念篇

 

  另附 JWT 的官方文檔: https://jwt.io/introduction/

 

二.python 對於 jwt 的實現, 目前已經存在了一些第三方的庫, 相信學習過 python 的程序猿都知道 itsdangerous 這個庫了, 它的底層原理就是基於 jwt 進行實現的

  這里需要進行提醒的是:

  itsdangerous (使用固定密鑰/字符串進行加密, jwt 有多種加密方式, 這只是其中一種, 建議先去了解一下)所生成的 token 仍然是可以被破譯從而看到 jwt 的 payload(有效負載) 里的數據, 只不過因為破譯者並不知道加密的密鑰, 也就無法對數據進行篡改, 所以如果是私密的數據, 就不應該使用 jwt 進行傳遞, 如 賬號的密碼, 以防止泄露. 如果需要傳遞私密數據, 解決辦法是,對 payload 的數據進行加密,從而杜絕非法破譯者看到 payload 內的任何信息,但是目前加密payload的操作不是很普及,在不加密 payload 的前提下, jwt 比較適合進行非受信任端的身份驗證, 此時即使接收方破譯了 token, 看到了 payload 的數據, 也不會造成太大的影響, 因為數據是無法被篡改的(當接收方將 token 值返回給服務器后, 需要使用相同的密鑰進行解密, 所以服務器的密鑰一定要保管好), 只要接收方將 token 原封不動的返回給服務器, 那么服務器就可以根據 token 值的內容來確認接收方身份的合法性,而不需要關心接收方是否看到過 payload 的內容.

  簡而言之, 除非額外對 payload 加密過, 否則就不要在 jwt 中傳遞不可被第三方獲知的私密數據

三. python實現生成 json web token

  環境: python3.6.7

  依賴包: jwt, time

  1)JWT 的簽名算法有三種。

    1.對稱加密HMAC【哈希消息驗證碼】  HS256/HS384/HS512   

      這種加密方式沒有公鑰,私鑰之分, 也就是只有一個密鑰, 這種加密方式適用於: 服務器將生成的jwt發送給接收方, 接收方將其返回給服務器, 服務器解析 jwt, 完成身份驗證.

     2.非對稱加密RSASSA【RSA簽名算法】RS256/RS384/RS512

     3.ECDSA【橢圓曲線數據簽名算法】 ES256/ES384/ES512

  2).對稱加密HMAC 生成 jwt

import time
import jwt

# payload
token_dict = {
    'iat': time.time(),  # 時間戳
   'name': 'lowman' # 自定義的參數
}
"""payload 中一些固定參數名稱的意義, 同時可以在payload中自定義參數"""
# iss issuer】發布者的url地址
# sub subject】該JWT所面向的用戶,用於處理特定應用,不是常用的字段
# aud audience】接受者的url地址
# exp expiration】 該jwt銷毀的時間;unix時間戳
# nbf not before】 該jwt的使用時間不能早於該時間;unix時間戳
# iat issued at】 該jwt的發布時間;unix 時間戳
# jti JWT ID】 該jwt的唯一ID編號

# headers headers = { 'alg': "HS256", # 聲明所使用的算法
}

"""headers 中一些固定參數名稱的意義"""
# jku: 發送JWK的地址;最好用HTTPS來傳輸
# jwk: 就是之前說的JWK
# kid: jwkID編號
# x5u: 指向一組X509公共證書的URL
# x5c: X509證書鏈
# x5tX509證書的SHA-1指紋
# x5t#S256: X509證書的SHA-256指紋
# typ: 在原本未加密的JWT的基礎上增加了 JOSE JOSE+ JSONJOSE序列化后文會說及。適用於JOSE標頭的對象與此JWT混合的情況。
# crit: 字符串數組,包含聲明的名稱,用作實現定義的擴展,必須由 this->JWT的解析器處理。不常見。

# 調用jwt庫,生成json web token jwt_token = jwt.encode(token_dict, # payload, 有效載體 "zhananbudanchou1234678", # 進行加密簽名的密鑰 algorithm="HS256", # 指明簽名算法方式, 默認也是HS256 headers=headers # json web token 數據結構包含兩部分, payload(有效載體), headers(標頭) ).decode('ascii') # python3 編碼后得到 bytes, 再進行解碼(指明解碼的格式), 得到一個str print(jwt_token)

# 個人測試生成結果如下: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ijk1MjcifQ.eyJpYXQiOjE1NTkyNzY5NDEuNDIwODgzNywibmFtZSI6Imxvd21hbiJ9.GyQhOJK8FKD_Gd-ggSEDPPP1Avmz3M5NDVnmfOfrEIY

  3) 使用 python 對 jwt 進行解析

 
         
import jwt

#
將上面生成的 jwt 進行解析認證 jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ijk1MjcifQ.eyJpYXQiOjE1NTkyNzY5NDEuNDIwODgzNywibmFtZSI6Imxvd21hbiJ9.GyQhOJK8FKD_Gd-ggSEDPPP1Avmz3M5NDVnmfOfrEIY" data = None try:   # 需要解析的 jwt 密鑰 使用和加密時相同的算法   data = jwt.decode(token, "zhananbudanchou1234678", algorithms=['HS256']) except Exception as e:   # 如果 jwt 被篡改過; 或者算法不正確; 如果設置有效時間, 過了有效期; 或者密鑰不相同; 都會拋出相應的異常   print(e) # 解析出來的就是 payload 內的數據 print(data)

# 輸出: {'iat': 1559276941.4208837, 'name': 'lowman'}

  

  4)如果是使用私鑰公鑰進行加密解密的方式(由請求方使用私鑰進行加密生成 jwt, 接收方使用公鑰解密), 只需要將相應參數更換成私鑰(將私鑰證書讀取出來, 賦值給相應參數即可), 並使用雙方約定好的的簽名算法

 

  5)  python 對於 jwt 的實現, 已經有了 itsdangerous 這個庫做了很好的支撐, 使用起來還是很方便的, 大家可以自行去了解一下.

    itsdangerous 官方文檔: https://itsdangerous.readthedocs.io/en/1.1.x/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM