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

一.關於 jwt 的原理及概念能夠自行在網絡上搜索瞭解一下,這裏推薦一篇寫的比較好的博客html

  深刻了解Json Web Token之概念篇python

 

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

 

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

  這裏須要進行提醒的是: json

  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", # 所使用的加密算法方式 'kid': "9527", # key_id
}

"""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, 有效載體 "zhananbudanchou9527269", # 進行加密簽名的密鑰 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, "zhananbudanchou9527269", 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/

相關文章
相關標籤/搜索