Python 详解PyJWT生成Token

JSON WEB Token(JWT),一种用以产生访问令牌(token)的开源标准;是目前Token鉴权机制下最流行的方案。 PyJWT是一个Python库,官方文档,安装如下:pip install pyjwt

jwt 编码

先上一张官方的图
在这里插入图片描述
我们参考上图来举个栗子!!!

import jwt
from datetime import datetime, timedelta

payload = {
    'exp': datetime.now() + timedelta(minutes=30),  # 令牌过期时间
    'username': 'BigFish' # 想要传递的信息,如用户名ID
}
key = 'SECRET_KEY'

encoded_jwt = jwt.encode(payload, key, algorithm='HS256')
print(encoded_jwt)
b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDM5MzA0NzMsInVzZXJuYW1lIjoiQmlnRmlzaCJ9.5eM02YL0xg1DiMZjx-muuYXahTm2etGOEeixFYYd7iI'

我们在jwt.encode函数中使用了三个参数:
1)第一个是payload,主要用来存放有效的信息,例如用户名,过期时间等想要传递的信息。payload字典内部官方指定有指定key,如exp用来指定token的生命周期。更多指定key参数可参考这里;
2)第二个key,一个秘钥字串,这个秘钥主要用在下文Signature签名中,服务端用来校验Token合法性,这个秘钥仅服务端知道,不能泄露。
3)第三个参数指定Signature签名所用的算法。

编码后的encoded_jwt就是我们要生成的Token。

感兴趣的话,我们进一步来了解下这串字符,观察JWT生成的Token'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDM5MzA0NzMsInVzZXJuYW1lIjoiQmlnRmlzaCJ9.5eM02YL0xg1DiMZjx-muuYXahTm2etGOEeixFYYd7iI'不难发现这是一条用两个点分割的长字符串,点分割成的三部分是:头信息(header), 消息体(payload)和签名(signature)。

①第一部分是对一个简单js对象的编码后的字符串,这个js对象是用来描述这个token类型以及使用的hash算法,我们对第一部分手动使用base64进行解码base64.b64decode('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9')会得到b'{"typ":"JWT","alg":"HS256"}'

②第二部分是token的核心,这部分同样是对一个js对象的编码,包含了一些摘要信息。有一些是必须的,有一些是选择性的。base64解码得到b'{"exp":1603930473,"username":"BigFish"}'
exp是expires的简写,是用来指定token的生命周期。username是我们选择性添加的用户信息。当然iss也有同等功效(iss是issuer的简写,表明请求的实体,可以是发出请求的用户的信息)更多参数查看文档。

③未签名的令牌由base64url编码的头信息和消息体拼接而成(使用"."分隔),签名(signature)则通过私有的key计算而成
unsignedToken = encodeBase64(header) + '.' + encodeBase64(payload)
signature = HMAC-SHA256(key, unsignedToken)

综上,JWT不会对结果进行加密,所以不要保存敏感信息在Header或者Payload中,服务端也主要依靠最后的Signature来验证Token是否有效以及有无被篡改。

jwt 解码

在这里插入图片描述
参看上图,jwt解码也很简单:

jwt.decode(encoded_jwt, 'SECRET_KEY', algorithms=['HS256'])

{'exp': 1603984192, 'username': 'BigFish'}

前面说过,JWT不会对结果进行加密,最后的Signature来验证Token是否有效以及有无被篡改。官网上也提供了jwt只解码而不验证的方法jwt.decode(encoded_jwt, verify=False)

JWT解码验证Token时候,我们一般用try…except…捕捉异常信息

其中常见的异常一般有:
exp指过期时间,在生成token时,可以设置该token的有效时间,如果我们设置30分钟过期,30分钟我们再解析此token会抛出jwt.exceptions.ExpiredSignatureError: Signature has expired
iss指的是该token的签发者,我们可以给他一个字符串。iss 在接收时如果不检验也没有问题,如果我们接收时需要检验但是又签名不一致,则会抛出jwt.exceptions.InvalidIssuerError: Invalid issuer
aud指定了接收者,接收者在接收时必须提供与token要求的一致的接收者(字符串),如果没写接收者或者接收者不一致会抛出jwt.exceptions.InvalidAudienceError: Invalid audience
iat指的是token的开始时间,如果当前时间在开始时间之前则抛出jwt.exceptions.InvalidIssuedAtError: Issued At claim (iat) cannot be in the future
nbf类似于token的 lat ,它指的是该token的生效时间,如果使用但是没到生效时间则抛出jwt.exceptions.ImmatureSignatureError: The token is not yet valid (nbf)
更多可查看API Reference

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值