JSON Web Tokens,是一種開(kāi)發(fā)的行業(yè)標(biāo)準(zhǔn) RFC 7519 ,用于安全的表示雙方之間的聲明。目前,jwt廣泛應(yīng)用在系統(tǒng)的用戶認(rèn)證方面,特別是現(xiàn)在前后端分離項(xiàng)目。
jwt方式
用戶登錄成功后,服務(wù)端通過(guò)jwt生成一個(gè)隨機(jī)token給用戶(服務(wù)端無(wú)需保留token),以后用戶再來(lái)訪問(wèn)時(shí)需攜帶token,服務(wù)端接收到token之后,通過(guò)jwt對(duì)token進(jìn)行校驗(yàn)是否超時(shí)、是否合法。
一、 jwt創(chuàng)建token
JWT原理
jwt的生成token格式如下,即:由 . 連接的三段字符串組成
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
生成規(guī)則如下:
-
第一段HEADER部分,固定包含算法和token類型,對(duì)此json進(jìn)行base64url加密,這就是token的第一段。
- 第二段PAYLOAD部分,包含一些數(shù)據(jù),對(duì)此json進(jìn)行base64url加密,這就是token的第二段
-
-
- 第三段SIGNATURE部分,把前兩段的base密文通過(guò)
. 拼接起來(lái),然后對(duì)其進(jìn)行HS256 加密,再然后對(duì)hs256 密文進(jìn)行base64url加密,最終得到token的第三段。
-
base64UrlEncode(header) + "." + base64UrlEncode(payload), your-256-bit-secret (秘鑰加鹽)
最后將三段字符串通過(guò) . 拼接起來(lái)就生成了jwt的token。
注意:base64url加密是先做base64加密,然后再將 - 替代 + 及 _ 替代 / 。
代碼實(shí)現(xiàn)
基于Python的pyjwt模塊創(chuàng)建jwt的token。
安裝
pip3 install pyjwt
實(shí)現(xiàn)
from jwt import exceptions SALT = 'iv%x6xo7l7_u9bf_u!9#g#m*)*=ej@bek5)(@u3kh*72+unjv=' 'username': 'wupeiqi', # 自定義用戶名 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=5) # 超時(shí)時(shí)間 result = jwt.encode(payload=payload, key=SALT, algorithm="HS256", headers=headers).decode('utf-8') if __name__ == '__main__':
jwt校驗(yàn)token
一般在認(rèn)證成功后,把jwt生成的token返回給用戶,以后用戶再次訪問(wèn)時(shí)候需要攜帶token,此時(shí)jwt需要對(duì)token進(jìn)行超時(shí) 及合法性 校驗(yàn)。
獲取token之后,會(huì)按照以下步驟進(jìn)行校驗(yàn):
-
將token分割成 header_segment 、payload_segment 、crypto_segment 三部分
-
對(duì)第一部分header_segment 進(jìn)行base64url解密,得到header
-
對(duì)第二部分payload_segment 進(jìn)行base64url解密,得到payload
-
對(duì)第三部分crypto_segment 進(jìn)行base64url解密,得到signature
-
對(duì)第三部分signature 部分?jǐn)?shù)據(jù)進(jìn)行合法性校驗(yàn)
from jwt import exceptions # 從token中獲取payload【不校驗(yàn)合法性】 # unverified_payload = jwt.decode(token, None, False) # print(unverified_payload) # 從token中獲取payload【校驗(yàn)合法性】 verified_payload = jwt.decode(token, SALT, True) except exceptions.ExpiredSignatureError: except jwt.InvalidTokenError: if __name__ == '__main__': token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NzM1NTU1NzksInVzZXJuYW1lIjoid3VwZWlxaSIsInVzZXJfaWQiOjF9.xj-7qSts6Yg5Ui55-aUOHJS4KSaeLq5weXMui2IIEJU" payload = get_payload(token)
文章來(lái)源https://www.cnblogs.com/wupeiqi/p/11854573.html
|