JWT令牌的生成和解令

mac2024-07-30  63

import base64 import copy import hmac import json import time class Jwt(): def __init__(self): pass @staticmethod def b64encode(j_s): #将加密后的等号用空字符进行替换 return base64.urlsafe_b64encode(j_s).replace(b'=',b'') @staticmethod def b64decode(b_s): #不全被替换掉的等号 为后面的提取时间做准备 rem=len(b_s)%4 if rem>0: b_s += b'='*(4-rem) #补全等号 #将中间的部分进行解码并返回 return base64.urlsafe_b64decode(b_s) @staticmethod #生成令牌 def encode(payload,key,exp=300): #对header进行base64转码 header ={'alg':'Hs256','ytp':'Jwt'} #给出header #separators:分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(‘,’,’:’);这表示dictionary内keys之间用“,”隔开,而KEY和value之间用“:”隔开。sort_keys是告诉编码器按照字典key排序(a到z)输出。 #生成header的json串 header_json=json.dumps(header,sort_keys=True,separators=(',',':')) #生成base64的header header_bs=Jwt.b64encode(header_json.encode()) #对payload进行base64转码 my_payload=copy.deepcopy(payload) #给出payload my_payload['exp']=time.time()+int(exp) #生成payload 的json串 payload_json=json.dumps(my_payload,sort_keys=True,separators=(',',':')) #生成payload进行base64转码 payload_bs=Jwt.b64encode(payload_json.encode()) #对sign进行base64转码 sign=[header_bs+payload_bs] if isinstance(key,str): # 判断key类型,为str 则转化为byte key=key.encode() hm=hmac.new(key,header_bs + b'.' +payload_bs, digestmod='SHA256') # 获取签名结果 hm_bs=Jwt.b64encode(hm.digest()) return header_bs + b'.' + payload_bs + b'.' +hm_bs @staticmethod def decode(jwt_s,key): #解令 #校验token #1,检查签名【前两项bs 再做一次hmac签名,与第三部分进行比较。若两者相等,校验成功;否则,失败】 #2, 检查时间戳是否过期【过期则 raise()】 #3, 返回payload铭文,也就是payload字典对象 header_bs,payload_bs,sign_bs=jwt_s.split(b'.') if isinstance(key,str): key=key.encode() hm=hmac.new(key,header_bs + b'.' + payload_bs, digestmod='SHA256') new_sign_bs=Jwt.b64encode(hm.digest()) if new_sign_bs != sign_bs: raise('不正确') #对payload解码(解令) payload_json = Jwt.b64decode(payload_bs) #json字符串 -> python对象 payload = json.loads(payload_json) #时间比较 exp = payload['exp'] now_t=time.time() if now_t > exp: raise ('已经过期') return payload if __name__ == '__main__': s=Jwt.encode({'username':'xiaoerlang'},'123456',100) print(s) d=Jwt.decode(s,'123456') print(d)

我自己使用时的结果:

b'eyJhbGciOiJIczI1NiIsInl0cCI6Ikp3dCJ9.eyJleHAiOjE1NzI1MjM2MDcuNDY5NjU5MywidXNlcm5hbWUiOiJ4aWFvZXJsYW5nIn0.0RDRL-Jgb7-q7UO46LT6W5DG3l-DfqSZ4k15hLqfdrM' {'exp': 1572523607.4696593, 'username': 'xiaoerlang'}

以上结果仅凭参考,由于时间的不同生成的结果也不同。为了进一步验证您的结果是否正确,可以使用JWT官网jtw官网进行结果验证。

最新回复(0)