使用JWT生成Token,并实现Token刷新API

这篇博客介绍了如何使用JWT生成Token,并实现Token刷新API。JWT作为一种轻量级的Token标准,满足了安全性及过期时间的需求。文章详细阐述了JWT的结构,以及在Python中使用pyjwt库生成和验证JWT的方法。此外,还展示了如何在实际项目中生成和验证Token,并设计了Token刷新API,允许在Token过期但refresh_exp字段未过期时获取新Token。
摘要由CSDN通过智能技术生成
一、背景

传统的网站用户认证方式严重依赖于 Cookie 。但 很多 项目是一个前后端分离的项目,我们希望前端界面的实现不受 项目API 的影响,这就要求 用户认证没有 Cookie 时也能进行。其实仔细想想,用户的认证鉴权,无非就是在访问 API 时发送一个能够识别出用户的字符串给服务端,然后服务端基于字符串查找出用户,再判断用户是否有权限使用 API 。这串字符串,我们可以将其称之为 Token。由于 rmon 的所有 API 都是基于 HTTP 协议的,而在 HTTP 协议中有一个 Authorization 的头部用于携带用户认证信息,所以我们可以将 Token 放在 HTTP 头部的 Authorization 字段中发送给服务端。需要注意的是,具体使用什么 HTTP 头部携带 Token 其实无关要紧,只需要服务端和客户端使用同样的头部进行处理就可以了。我们选择 Authorization 头部,是因为在相关标准中 Authorization 头部被指定用于实现 HTTP 基本认证。

Token 一般是由服务端下发的,用户在成功登录后,服务端将发送一个 Token,后续的所有的访问中,客户端都将携带这个 Token,而服务端都将基于该 Token 进行用户认证鉴权。由于任何人拿到这个 Token 后就相当于盗取了用户的所有操作权限,所以 Token 的安全性非常重要。因此 Token 有一些要求,例如 Token 需要有一个过期时间,过期后 Token 就作废,服务端收到 Token 时需要验证其是否已经过期。此外需要有一种办法确保服务端发出的 Token 没有被篡改,如果不能验证 Token 是否被篡改,就无法保证 Token 代表的用户是其未被篡改前代表的用户。从零开始实现这些需求非常麻烦,好在我们可以使用 JWT。

二、使用JWT生成Token

JWT 全称为 Json Web Token,是一种轻量的 Token 实现标准, 它满足了我们对 Token 的所有需求,而且使用简单。一个 JWT 由 . 符号分隔成三部分,如下所示:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiIxMjMiLCJleHAiOjE1MDk0OTc2NDZ9.1tCu1bjfveMfMhj5C6nR5P9iRm-O_Z7rSFnmj_BmMno

每一部分都是经过 Base64 编码的,且前两部分都是 json 字符串其中第一部分被称为头部,包含了 JWT 的签名方式,也就是前文中防止被篡改所使用的算法,例如下面的头部:

{
   
  "typ": "JWT",
  "alg": "HS256"
}

其中 type 字段说明是 JWT,alg 字段值指明了签名所使用的算法。

第二部分被称为 payload 也就是载荷,包含了用户自定义的字段信息和 JWT 标准的字段信息。例如前文所述要通过 Token 传递能够识别出用户身份的标示符,那么标示符就应该放在 JWT 的 payload 中。标准的字段主要有下面几种:

  • iss: JWT 签发者
  • sub: JWT 所面向的用户
  • exp: JWT 的过期时间,这个过期时间必须要大于签发时间
  • nbf: 定义在什么时间之前,该 JWT 都是不可用的
  • iat: JWT 的签发时间

一个有效的 payload 如下:

{
   
  "uid": "123",
  "exp": 1509497646
}

包含了一个自定义的信息字段 uid 代表用户 ID,和一个标准的 exp 字段。对于一个 JWT 来说,我们可以直接通过对第二部分进行 base64 解码得到其具体内容,这就要求我们不能将机密信息放入 JWT 的第二部分中,比如用户密码。第三部分则是基于前两部分内容生成的签名字符串

在 Python 中可以使用 pyjwt 软件包用于生成 JWT 和验证 JWT。基本的使用方法如下图所示:
在这里插入图片描述
我们主要使用 jwt.encode 和 jwt.decode 方法实现生成和读取 JWT 的操作。调用 jwt.decode 的时候可以通过参数指定是否对 JWT 进行验证,比如验证过期时间,验证签名信息是否正确等等。

总结下,用户通过登录认证 API 进行登录,服务端验证用户发送的用户名和密码是否正确,如果正确则返回一个 JWT 给用户;此后用户访问其它 API 时,例如管理 Redis 服务器时,则需要携带 JWT ;服务端收到请求后验证 JWT,查看相应的用户是否有访问权限。

项目实际使用

generate_token 实例方法,用于产生用户实例对应的 JWT,代码如下:

    def generate_token(self):
        """生成 json web token

        生成 token,有效期为 1 天,过期后十分钟内可以使用老 token 刷新获取新的
        token
        """
        # 设置 token 的过期时间为 1 天
        exp = datetime.utcnow() + timedelta(days=1)
        # token 过期后 10 分钟内,可以刷新旧的 token 获取新 token
        # datetime.datetime 对象的 utctimetuple 方法的返回值
        # 是 time.struct_time 对象,该对象为类 tuple 对象
        struct_time = (exp + timedelta(minutes=10))
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值