Golang - 双Token认证
前言
学会如何在 Golang 开发中使用双Token进行验证。
什么是 JWT ?
jwt
:是 json web token 的缩写,jwt 是服务端通过特定算法生成的的一个凭证信息,主要包含Header
(头部)、Payload
(载荷)、Signature
(签名)。因为http 是无状态的,所以客户端触发的http请求我们不知道用户的状态信息,比如这个用户已经登陆过了。所以衍生出
Header
令牌头部,记录了整个令牌的类型和签名算法,它是一个描述 jwt元数据的 json 对象
Payload
JWT 第二部分是 Payload,也是一个 Json 对象,除了包含需要传递的数据,还有七个默认的字段供选择。
一般来说 至少要使用 iss 和 exp 。
- iss (issuer):签发人/发行人
- sub (subject):主题
- aud (audience):用户
- exp (expiration time):过期时间
- nbf (Not Before):生效时间,在此之前是无效的
- iat (Issued At):签发时间
- jti (JWT ID):用于标识该 JWT
SIgnature
JWT 第三部分是签名,主要的生成步骤有以下几点。
- 首先需要指定一个 secret,该 secret 仅仅保存在服务器中,保证不能让其他用户知道。这个部分需要 base64URL 加密后的 header 和 base64URL 加密后的 payload 使用
- 然后通过header 中声明的加密算法 进行加盐secret组合加密,然后就得出一个签名哈希,也就是Signature,且无法反向解密。
校验jwt
当服务端生成jwt传递给前端后,前端保存 jwt 信息到浏览器本地,后续请求附加到请求头的 Authorization 中,服务端通过 jwt 的
Header
和Payload
用同一套哈希算法和同一个secret
计算签名值,让后把计算结果和前端传递的 jwt 第三段进行比较如果相同那么就通过验证,
小结
jwt 出现场景
jwt 的出现是因为 http 是无状态的,并且因为使用算法进行计算校验相比服务端存储Session 节省更多资源 jwt 能够适用于更多的场景。
jwt 优缺点
优点
- 持久性:服务端不用存储生成的 jwt 信息,服务器即便重启后也能对历史的 jwt 进行校验。
- 节省资源:相对于通过 Session 存储用户的会话信息,服务端可以节省更多资源。
缺点
- 安全性:因为可以存储在客户端,那么数据就可以被篡改,并且
Payload
部分没有加密,只是使用了Base64进行编码,所以 jwt 不能存储敏感信息。 - 无法中途废弃:jwt 一旦进行签发,那么只能等到该凭据自动过期,无法强制过期,所以使用时应该尽量用合适的过期时间去签发。(双Token解决)
- 续签问题:jwt 什么时候续签?如果续签频繁就违背了 jwt 的设计初衷,如果不续签,又影响用户体验。(双Token 解决)
Golang:双Token续签
实现思想
根据上面的jwt的缺点,我们可以分析道,jwt 续签才是问题所在,那么只要优雅的解决续签问题,其他的就好说了。
1.短Token
我们简称 Authorization 为Atoken,他是一个包含用户信息的主体Token用来,是用户访问权限校验的真实Toekn。所以短Token的生命周期很短,但是维护要很频繁,我们这里设置过期时间为2小时。
2. 长Token
我们简称 Reflash 为 Rtoken,他是一个用来帮助刷新Atoken的凭证,所以它不需要记录用户的信息,因此它需要一个较长的生命周期来保证维护短Token的更新。我们这里设置过期时间为 7 天
3.代码总览
核心思想就是:Atoken 肯定会先过期,过期后如果在Rtoken的时间范围内,那么重新生成Atoken。以此来进行维护更新。
1 |
|