每月一争, 为什么 JWT 这么多诟病, 什么下线设备登录 JWT 不是很容易解决吗?

328 天前
 seth19960929

JWT 的基本就不再过多阐述

思考的问题前提: 比如我们面对一个千万级用户的系统. * 客户端需要和服务端交互, 假设 50% 的接口需要校验 * 10% 的接口需要获取个人信息


至于常见的 JWT 诟病解决方案

为什么要用 JWT ?

下线, 黑名单为什么不直接存储 token ?

5156 次点击
所在节点    问与答
55 条回复
seth19960929
328 天前
还有 access_token 一个就够了, 为什么还要有 refresh_token, 除了官方说的安全之外, 就是可以作为两个时间点去使用.
access_token 每次都要校验, 可以简单的校验, refresh_token 使用的频次比较少, 这时候可以做更完整的校验.
LeegoYih
328 天前
用了 JWT 还要存 token 到服务端,每次还要查版本号和黑名单,不是脱裤子放屁吗?
用户权限之类的更新了怎么办?难道让用户退出重新登录一遍吗?
查一次缓存就能解决的事情,不要太小看 Redis 的性能了。

而且 JWT 不是 100%安全的: https://github.com/yihleego/jwtcrack
oldshensheep
328 天前
你这个都依赖 **分钟级别过期 access_token**

你加个 token_version 那每次刷新 jwt 就要查询数据库,而且你刷新的非常频繁,这不又和原来一样
同样的还有检查 device_id 要查询数据库
giter
328 天前
我选择把 accessToken 与 refreshToken 存在 localStorage 中。既然要 JWT ,那就贯彻到底,给服务端彻底减负。
nomagick
328 天前
jwt 真正的用途在于验证其他站点的用户和 token ,而不是自己站点的。
不要为了用而用。
ztxcccc
328 天前
别查库了谢谢
amlee
328 天前
jwt 的设计初衷就是要无状态,如果你的需求必须要求有状态,那么 jwt 的设计不适合你,为什么不用现成的 session 方案?
这本质上是一个需求和设计是否匹配的问题,搞清问题本质,跟技术优劣,或者说能否给技术打补丁以满足需求没关系。
板砖和锤子都能敲钉子,你非要说我能打磨一个完美的板砖去敲钉子,那我只能说脑子有包
gogola
328 天前
@LeegoYih #2
暴力破解这玩意,不好说。
CodeCodeStudy
328 天前
token 存 redis 不就完事了?
emric
328 天前
我这边用 last_login ,日期不相同就拒绝。
感觉你说的大部分问题,都是修改以下 last_login 就行。
seth19960929
328 天前
@LeegoYih 我就问一下, 你使用 token 权限更新了怎么办? 这个和 jwt 没关系. 你权限更新其它方式该怎么做就怎么做. 不是我小看, 而是如果还不消耗存储, 不消耗 io 的方式为什么不讨论呢?

@oldshensheep token 的方式, 按用户级别来说, 每次请求来都查 redis, 并且 jwt 包含千万级别的用户数据, 而刷新的时候查询, 减少了 90% 的请求, 并且 redis 的存储只用非常少
@giter 没错了, 那肯定都要存客户端的, 和我说的没区别
@nomagick 你在哪看的定义? 你说的是 oauth2 吧
@ztxcccc 举个栗子
@amlee 又来一个不看解决方案, 上来就说不查库的
seth19960929
328 天前
@CodeCodeStudy 话说不看场景直接就存?
@emric 原理方案差不多的, 总是有些人在说为什么不存 redis 呢. 所以要讲这个东西.
ellermister
328 天前
那每个 jwt 请求到服务端不都是要查一下有没有在 redis 黑名单列表里,千万级的用户也是千万级的查询啊,jwt 只是把 redis 存储大小改了,没改变查询次数。
@seth19960929
seth19960929
328 天前
@LeegoYih 我看了两眼你这个代码, 上来来个碰撞代码就说不安全, 能拿出具体的文献出来吗.
按你这样子说, 世界上没有安全的加密, 我只要写一个碰撞代码, 它们安全只是我现在没有碰撞到, 不代表我做不到.
seth19960929
328 天前
@ellermister 嗯嗯, 这是一个讨论帖子.
两种方案:
1. 只在刷新 token 的时候才查询是否在黑名单, 请求可以降低非常多, 有个问题就是会有延迟, 比如 5 分钟刷新一次 token, 那么就会加入后有 5 分钟延迟. 如果是部分场景完全可以用这种(只要 app 左右逻辑处理, 能及时失效, 如果有人窃取了 token, 那么它也只能使用 5 分钟, 到期了刷新就会得知被加入黑名单)
2. 大小还是差别很多的. 往 redis 里存 32 位字符串 key 1000w 个看看. 我等会给一个答案
LeegoYih
328 天前
8355
328 天前
只用 jwt 没有防御措施绝对是错误的行为

单 ip 连续请求错误 token 值为不可信行为,这是风控策略应该做的事
在敏感操作必要时进行密码检查

仅传入 token 就给予最大用户操作权限本身就不合理
wunonglin
328 天前
你说得对
Masoud2023
328 天前
你文中的黑名单和单台设备下线,归根结底都是要去查库,那用 jwt 和不用 jwt 做 sessionid 有什么区别么
seth19960929
328 天前
@LeegoYih
只要循环结束, 我一样能破解呀.

for ($i = 1; $i < pow(32, 16); $i++) {
$key = genKey($i);
$result = openssl_decrypt(hex2bin('1fbf2605f954fad3ba18115000735aee'), 'aes-128-cbc', $key, 1, '0000000000000000');
}

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

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

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

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

© 2021 V2EX