请教大家一个关于 RESTFul 认证的问题:如何保证一个用户只能有一个 JWT( Json Web Token)

2016-11-15 17:09:07 +08:00
 mynameisny

本人菜鸟,目前在开发几个 RESTFul API 。现在遇见一个头疼的问题,希望大家不吝指教:

如何能保证一个用户在一段时间内只能有一个 Token 是可用的?

---- 用户在某一个时刻只能有一个有效 Token ,即,用户已有一个有效 Token 时,再次请求 Token 时要作废之前生成的那个 Token 。

实际的业务流程是:

目前采用的方案是:

问题和纠结是:

19228 次点击
所在节点    问与答
23 条回复
Clarencep
2016-11-15 17:18:37 +08:00
“但是如果用户写好的某个调用程序正在执行,不小心又重新生成了一个 Token ,那么调用就会停止。” -- 这种情况一般不需要考虑, 可以参考下各大开发平台的 API (如微信和支付宝)。
mynameisny
2016-11-15 17:21:08 +08:00
@Clarencep 哦哦哦。了解了,这种属于应该操作失误吧。不知纠结一是不是可以给些指点?想保证唯一 Token ,应该怎样搞……
ty89
2016-11-15 17:32:39 +08:00
看你正文里面写到,“ token 保存在 Redis 中,以用户名作为 Key “,这样的话如果你的生成 token 的算法没毛病,就可以认为是唯一的了。不知道你纠结的点在哪里。
ty89
2016-11-15 17:34:55 +08:00
至于第二点,你担心得完全多余了。
mynameisny
2016-11-15 17:43:19 +08:00
@ty89 纠结之处在于好多资料上说, JWT 生成 Token 是不应该放在服务器端保存起来的,但是不记录它的状态怎么能知道它只有一份呢?
xxxyyy
2016-11-15 17:47:14 +08:00
你反过来做就行了,只保存吊销的 token ,在鉴权时查看下 token 是否在 redis 中,如果在就拒绝就可以了,在保存到 redis 的 token 还可以设置一个 ttl ,时间是 token 的过期时间,这样就不需要手动去清理 redis 里的 token 了。
mynameisny
2016-11-15 17:52:28 +08:00
@xxxyyy 感谢回复,我现在就是这么做的呢,依赖于 Redis 的 TTL ,过期了就会把那个 Token 自动的删除,如果 Token 不存在了就不准调用。关键的问题还是这个 Token 要保存的问题,是不是我的这个情景里是必须要在服务器保持一份 Token 呢?
xxxyyy
2016-11-15 17:54:05 +08:00
@mynameisny 为什么要保存 token ?
Herobs
2016-11-15 17:56:48 +08:00
token 本身就携带了足够多的信息,包括过期时间。泄漏的话,只会是在有效期内存在风险,这个是可以接受的。

把 token 存起来是完全没有意义的, JWT 就是用来去中心化,达到 stateless 的目的。
mynameisny
2016-11-15 17:58:45 +08:00
@xxxyyy 是希望保证让一个用户在一段时间内只有一个 Token 是有效的。
mcfog
2016-11-15 18:00:55 +08:00
简单研究过 jwt 。个人不建议用 jwt 作 session 用途。原因基本和你的纠结一样, jwt 最大的好处就是把数据带到前端去转了一圈,从而能实现无状态服务端,但 session 这件事天生就是关于维持状态的,和 jwt 是矛盾的。有状态的服务直接发 uuid 作 session key 就好

另外 jwt 之前很多开源实现暴露过致命漏洞(客户端可以直接构造加密方式为不加密的 token 通过校验)这也让我对 jwt 的影响分大减,说白了 jwt 就是参数头+body 的一个约定而已,和自己定协议唯一的区别就是他开源,有三方库,但这些库的质量如果没保证的话,还不如自己定协议靠谱。毕竟自己写代码出 bug 那是自己水平不够测试不严,用三方库出 bug 那完全是吃苍蝇

建议阅读:

http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/
https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
mynameisny
2016-11-15 18:02:26 +08:00
@Herobs 对对,我就是看到了很多关于 JWT stateless 方面的介绍才来求助的。如果不考虑泄漏的情况,只是不希望用户有多个 Token 同时可用,是不是我现在的这个问题就限制在必须是有一个“中心”了呢?
Herobs
2016-11-15 18:06:03 +08:00
@mynameisny 不希望用户有多个 token 同时有效的目的是什么,如果非要达到这个目的,可以考虑为每个用户维护一个递增的整数,来达到节省资源的目的。
xxxyyy
2016-11-15 18:08:23 +08:00
要保证让一个用户在一段时间内只有一个 Token 是有效,这就产生状态了,需要服务器端保存这个状态才行。
mynameisny
2016-11-15 18:11:43 +08:00
@mcfog 受教受教!! JWT 和 Session 关于状态果真是矛盾的。其实我现在的方案中是在借用了 JWT 生成 Token 的功能而已,完全没有使用它无状态的特性。我只是享受到了一个确定草案的开源实现而已……如您所言,我完成可以自己实现一个约定,能解密调用者传递来的 Token ,解析出我想要信息,并保证 Token 唯一就可以了。
mynameisny
2016-11-15 18:12:42 +08:00
@xxxyyy 是是是,感谢众高手们的指点,是我误用 JWT 了,我确实是需要带“状态”的 Token 。
ctsed
2016-11-15 18:59:20 +08:00
我打开俩帖子,第一个帖子需要刷新一下才能回复?
caixiexin
2016-11-15 19:04:32 +08:00
用 jwt 做认证的话,不需要在服务的保存它,这有篇文章讲的挺清楚的。
http://blog.leapoahead.com/2015/09/07/user-authentication-with-jwt/
Koyoter
2016-11-15 19:17:24 +08:00
token 绑定 ip 或者 mac 地址?变了就算下线
mynameisny
2016-11-15 19:48:37 +08:00
@caixiexin mcfog 11 楼和 xxxyyy 14 楼的回复是很精僻的, Token 本身是不需要状态的,但是限定了它在一段时间只有唯一实例,就是产生状态了,一旦产生了状态了就成了“ SESSION ”

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/320710

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX