JWT令牌的生成和解令

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值