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官网进行结果验证。