现在不是流行restful么,认证的时候用jwt,token有过期时间,有人说时间越短越好,
那过期后怎么认证,要在登录吗,过期时间多久比较好
现在不是流行restful么,认证的时候用jwt,token有过期时间,有人说时间越短越好,
那过期后怎么认证,要在登录吗,过期时间多久比较好
1、用户登录返回两个token,accessToken 1小时有效期(可根据需求调整),refreshToken 7天有效期
2、客户端统一处理token过期请求,如果捕获到这个过期请求,先刷新token,再自动重放请求。
3、用户退出登录,将token放入黑名单
4、并发问题也不存在,如果上一个请求发现token失效,需要重新发送请求时,先查本地token是否刷新,刷新过就直接重新请求。
这个并不是答案,放在这里而不是评论区是为了更多的人看到,不要踩我?
@lsxiao 你提出这个并发问题我才意识到jwt的这个缺陷,不过读到https://segmentfault.com/q/10... 这里@我只想帮妈妈洗碗 的回答我突然想到:
如果不是持续刷新token,而是过期前3分钟刷新token,刷新token把旧的token放入黑名单。后续校验一个token是不是在黑名单的时候放宽1分钟(就算在黑名单,但是距离放入黑名单的时间小于1分钟认为有效)就可以解决新token发放后旧token的请求失败的问题。
所以jwt的方案还是要有数据库存储黑名单的,不然没办法解决注销问题(但如果有数据库的存在,跨服务器的校验又是一个问题,如果再弄个认证服务器,感觉更复杂了)。现在还是非常困扰怎么更合理的解决jwt的续签和注销的问题。没有看到比较完善的文档。望大神们指教?
更新:
最近又对这个问题思考了一下,意识到并发问题其实是自寻烦恼,并发的起源是黑名单,加入黑名单的原因是要续签,所以最根本的问题是续签问题。那么续签的方式其实跟cookie是两个方式:
那么黑名单其实是为了解决另外一个问题——注销,如果需要强制退出用户登录,那么后端就需要有个黑名单,每次解码前/后要进行数据库读取是否是黑名单。这个对于单类型客户端(同类型客户端登录互斥需求)是有必要存在的,总体来讲如果加解密开销影响较小的话,读黑名单的成本要比维护session低的多(量少)。
至于@faceair 的说法,是后续读到一篇文章(讲真,别再使用JWT了)(不过作者的观点说又重新发明了session,可是为什么session就不能重新发明呢?)才理解什么意思,他其实说的是一次性授权,这个过程理论上是连续的,而且有时间限制,还有就是授权只生效一次(比如跳到第三方进行支付),所以不存在续签问题,那么这个时间究竟是多久应该参照业务。当然他的说法还有点类似oauth2的应用。
这个问题之前写过一篇稿子的思考:
关于jwt的思考
但是还不完善,后续如果有进一步深入会再更新一下博文,写的不好,请轻踩。
“时间越短越好”,肯定不对啦。。。那我断到0.000001ms过期,那都没有意义了。。。
合理多久过期,可以看下weibo的时间。然后结合自己的产品特性定一个时间。(貌似weibo是一周?忘记了。oschina貌似2~3个星期。主要是oschina都是读一些公共的信息业务比较多。)
(好吧。没看清楚是jwt。忽略我的错误回复)
JWT 过期时间尽可能的设置短,我这边是 1 分钟左右,随着 JWT Token 一起发送的还有
Refresh_token,Refresh_token 我是这么设计的 MD5(randomString),然后以 Refresh_token 为 key,有效期为value存入数据库或者 Redis 之类的,设计一个中间件,检查 JWT Token 时间,JWT Token过期的话,检查 Refresh_token 是否过期,Refresh_token 没有过期的生成新的 JWT Token 和 Refresh_token 返回给客户端,这样既解决了 JWT Token 时间过长 重放攻击问题,又避免了频繁登录问题。关键是 Refresh_token
楼上的你们都在说啥。。。
jwt的认证方式跟oauth2不一样,所有用户信息是一次性全部交换,token里面包含了用户信息和过期时间,这个时间是服务端定义的。如果这个失效时间太长,那么这个token会长期有效,无法抵御重放式攻击。
一般认证过程是连续的,个人建议这个时间5S左右就够了。
客户端应该严格遵循这个过期时间的限制,过期的token直接丢弃。不存在过期后怎么认证的问题,用户信息是一次性给的。
如果要更新用户信息,需要用户重新jwt授权,这边才能更新。具体的更新时间自己把握,可以用户每次用jwt登录过来的时候更新一遍用户信息。
参考 https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.4
1 回答1k 阅读✓ 已解决
1 回答1k 阅读✓ 已解决
1 回答395 阅读✓ 已解决
1 回答599 阅读
楼上的都在说什么!不要乱误导人!你们到底看过 RFC7519 文档吗,你们有实现过JWT吗?!
第一名说过期时间5秒的也是够了,居然还有赞!!!!
segmentfualt现在的回答都是这种水准吗?
JWT实现的时候,一般会有两个过期时间
第一个是Token本身的过期时间,这个时间一般1到2个小时,不能太长,也可以在短一点,不过5s的简直纯属扯淡。
第二个是Token过期后,再次刷新的有效期,也就是Token过期后,你还有一段时间可以重新刷新,把过期的Token发给服务端,如果没有过刷新截止期,则服务端返回一个新的Token,不再需要通过用户名密码重新登录获取Token了。
所以为了减少过期后重新获取Token所带来的麻烦,我们一般在每次Http请求成功后,将目前的Token刷新,然后可以在Http响应中返回新的Token。
JWT由于过期数据(exp claim)是封装在Payload中的,所以必须返回一个新Token,而不是在旧Token的基础上刷新。
但是在并发的时候也会出现问题,如果前一个请求刷新了Token(为了安全,刷新后一般会把旧Token加入黑名单),后面的请求使用了一个旧的Token像服务请求数据,这个时候请求会被拒绝。
可以说这真的是JWT的一个缺陷,目前没有特别好的办法来解决并发刷新的问题。
不过可以通过设置一个宽限时间,在Token刷新后,如果旧Token仍处于刷新宽限时间内,就放行。
我最近在写一个JWT的扩展包,给Lumen用的,如果想了解一些JWT的原理,构成,可以关注我的专栏,和这个系列的文章。
Code杂货铺-lsxiao的知乎专栏
从零实现Lumen-JWT扩展包