使用redis实现refresh token

四糸乃赛高 Lv.5 冰封大地
42 2022/8/25笔记
什么是JWT
JWT(JSON Web Token) 是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。
JWT结构

JWT由三部分组成,头部(Header)、负载(Payload)、签名(Signature),在传输JWT时会将这三部分进行base64编码,用.连接。

例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 

头部的包含签名的算法和这个token的类型;负载包含一个JSON对象,存放需要传输的数据,一般会包含字段exp(过期时间)、iat(签发时间)、nbf(生效时间);签名部分是对前两部分的签名,防止数据被篡改,签名使用指定秘钥(secret)和头部指定的签名算法生成。

使用JWT时存在的问题

1、JWT签发后,在到期前会一直有效。当一个用户生成新的JWT时,需要销毁之前生成的JWT。

2、JWT泄露后,任何人都能使用该token与服务器交换数据。


Refresh Token

OAuth2.0中的一个概念,用于在access token过期后刷新access token的一个令牌。

我的实现思路:

用户登录时,生成access token(下文简称at)时,将at存入redis,并设置过期时间(短时间),同时判断redis中是否有refresh Token(下文简称rt),有则取出并与at一起返回,无则生成,并存入redis,设置过期时间(长时间)。当用户使用at请求接口时,对该at与redis中存入的at进行匹配,失败则校验失败。

当用户调用刷新令牌的接口时,如果rt没有过期,则生成新的at存入redis,如果rt过期,则需要用户重新登录。

当at中的数据过大时,存入redis会影响性能,我想的解决方案是存入该at的特征,比如该at的16位md5,存入的at key可为user:token:userID,rt则为 user:rt:userID

具体的代码可以看看本博客的源码  

https://gitee.com/yoshinosk/blog/blob/master/server/utils/middlewares.js

https://gitee.com/yoshinosk/blog/blob/master/server/utils/user.js


关于JWT的存储

当时比较纠结,查了不少文章,最后得出的结论是“不要将token存在能够使用js脚本获取的任何地方”。

比如本博客at是存在vuex中,rt则存在cookie,服务端设置了httpOnly后,能够阻止客户端脚本访问cookie。


参考文章:

JSON Web Token 入门教程

Refresh Token介绍

# redis

评论

后参与评论
还没有评论,来说点什么吧~