JWT

本文介绍了JWT(JSON Web Token)的结构和使用方法,包括Header、Payload和Signature三部分的详细解释,以及如何进行签名和校验。还提到了Python中使用pyjwt库进行JWT操作的示例,包括encode和decode函数的使用,并通过示例展示了过期时间的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1,header

​ 格式为字典-元数据格式如下

{‘alg’:‘HS256’, ‘typ’:‘JWT’}
#alg代表要使用的 算法
#typ表明该token的类别 - 此处必须为 大写的 JWT
1
2
3
​ 该部分数据需要转成json串并用base64 加密

​ 2,payload

​ 格式为字典-此部分分为公有声明和私有声明

公共声明:JWT提供了内置关键字用于描述常见的问题
1
此部分均为可选项,用户根据自己需求 按需添加key,常见公共声明如下:

{‘exp’:xxx, # Expiration Time 此token的过期时间的时间戳
‘iss’:xxx,# (Issuer) Claim 指明此token的签发者
‘aud’:xxx, #(Audience) Claim 指明此token的
‘iat’:xxx, # (Issued At) Claim 指明此创建时间的时间戳
‘aud’:xxx, # (Audience) Claim 指明此token签发面向群体
}
1
2
3
4
5
6
​ 私有声明:用户可根据自己业务需求,添加自定义的key,例如如下:

{‘username’: ‘guoxiaonao’}
1
​ 公共声明和私有声明均在同一个字典中;转成json串并用base64加密

​ 3,signature 签名

​ 签名规则如下:

​ 根据header中的alg确定 具体算法,以下用 HS256为例

​ HS256(自定义的key , base64后的header + b’.’ + base64后的payload)

​ 解释:用自定义的key, 对base64后的header + b’.’ + base64后的payload进行hmac计算

2,jwt结果格式
​ base64(header) + b’.’ + base64(payload) + b’.’ + base64(sign)

​ 最终结果如下: b’eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imd1b3hpYW9uYW8iLCJpc3MiOiJnZ2cifQ.Zzg1u55DCBqPRGf9z3-NAn4kbA-MJN83SxyLFfc5mmM’

import base64
import json
import copy
import time
import hmac
class JWT:
def init(self):
pass

@staticmethod
def encode(payload,key,exp=300):
    #init header
    header = {'alg':'HS256','typ':'JWT'}
    #将header 转成json串
    header_json = json.dumps(header,sort_keys=True,separators=(',',':'))
    #base64 - json串
    header_bs = base64.urlsafe_b64encode(header_json.encode())

    #init payload {'username':'guoxiaonao'}
    payload = copy.deepcopy(payload)
    payload['exp'] = time.time() + exp
    payload_json = json.dumps(payload,sort_keys=True,separators=(',',':'))
    payload_bs = base64.urlsafe_b64encode(payload_json.encode())

    if isinstance(key,str):
        key = key.encode()

    #sign
    hm = hmac.new(key,header_bs+ b'.' +payload_bs,digestmod='SHA256')
    hm_bs = base64.urlsafe_b64encode(hm.digest())

    return header_bs + b'.' + payload_bs + b'.' + hm_bs

if name == ‘main’:

res = JWT.encode({'username':'guoxiaonao',},'123456')
print(res)

结果:
b’eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NjkzMTIyMjAuNjIyODg3LCJ1c2VybmFtZSI6Imd1b3hpYW9uYW8ifQ==.eqOdC9mh-puGT3Dx-KKCVtEWByplZeKVLgx0a_NRYsw=’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
3,校验jwt规则
​ 1,解析header, 确认alg

​ 2,签名校验 - 根据传过来的header和payload按 alg指明的算法进行签名,将签名结果和传过来的sign进行对比,若对比一致,则校验通过

​ 3,获取payload自定义内容
4,若payload中含有exp,则校验过期时间

4,pyjwt
​ 1,安装 pip3 install pyjwt

方法 参数说明 返回值
encode(payload, key, algorithm) payload: jwt三大组成中的payload,需要组成字典,按需添加公有声明和私有声明
例如: {‘username’: ‘guoxiaonao’, ‘exp’: 1562475112}
参数类型: dict token串
返回类型:bytes
key : 自定义的加密key
参数类型:str
algorithm: 需要使用的加密算法[HS256, RSA256等]
参数类型:str
decode(token,key,algorithm,) token: token串
参数类型: bytes/str payload明文
返回类型:dict
key : 自定义的加密key ,需要跟encode中的key保持一致
参数类型:str
algorithm: 同encode
issuer: 发布者,若encode payload中添加 ‘iss’ 字段,则可针对该字段校验
参数类型:str 若iss校验失败,则抛出jwt.InvalidIssuerError
audience:签发的受众群体,若encode payload中添加’aud’字段,则可针对该字段校验
参数类型:str 若aud校验失败,则抛出jwt.InvalidAudienceError
PS: 若encode得时候 payload中添加了exp字段; 则exp字段得值需为 当前时间戳+此token得有效期时间, 例如希望token 300秒后过期 {‘exp’: time.time() + 300}; 在执行decode时,若检查到exp字段,且token过期,则抛出jwt.ExpiredSignatureError

In [1]: import jwt

In [2]: jwt.encode({‘username’:‘guoxiaonao’},‘123456’,algorithm=‘HS256’)
Out[2]: b’eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imd1b3hpYW9uYW8ifQ.kgWAwfADg3M79kr0rX3GW5zrkFdpUK2Uq_9qnQ9Ub4I’

In [3]: s = jwt.encode({‘username’:‘guoxiaonao’},‘123456’,algorithm=‘HS256’)

In [4]: jwt.decode(s,‘123456’,algorithm = ‘HS256’)
Out[4]: {‘username’: ‘guoxiaonao’}

这里面的’123456’是key,这个调包还是比较方便的~
1
2
3
4
5
6
7
8
9
10
11
我自己写的.py文件,可以切换time.sleep()来查看不同的结果,假如成功就会解析出信息,假如token过时,就会报错

import time
import jwt
def make_token(username, expire=3):
key = ‘123456’
now_t = time.time()
payload = {‘username’: username, ‘exp’: now_t + expire}
return jwt.encode(payload, key, algorithm=‘HS256’)

def func():
try:
b = make_token(‘123’)
# time.sleep(2)
time.sleep(4)
a = jwt.decode(b,‘123456’,algorithms=‘HS256’)
print(a)
except Exception as e:
print(e)

func()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值