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

353 天前
 seth19960929

JWT 的基本就不再过多阐述

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


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

为什么要用 JWT ?

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

5217 次点击
所在节点    问与答
55 条回复
seth19960929
353 天前
@8355 这个是,敏感操作已经和是 token 还是 jwt 没关系
@wunonglin 你说得对
@Masoud2023 sessionid 存取 1000w 数据, 没有哪家的黑名单有 1000w 吧? 并且我可以在刷新 token 的时候再查 redis, 而不是每次请求.
nothingistrue
353 天前
JWT 全称是 Javascript Web Token 。它与传统 Token 的唯一区别就是它采用非对称加密的方式。这有两个好处:一,可以自验证;二,可以携带更多的信息(传统 Token 采用 MD5 、SHA1 这样的散列加密方式,这是无法自验证和反解码的)。

JWT 只是一个高级的 Token 而已,并不是会话 /用户跟踪方案,在会话跟踪方案上讨论 JWT 的优劣根本毫无意义。而 2 楼这种比较,是想把 Token 、会话跟踪、认证(用户)、授权(权限)糅合到一起去考虑,神仙看了都会躲。

楼主说得实质上是 Token 采用 JWT 的会话跟踪方案。在会话跟踪方案上,用 JWT 代替普通 Token 、SessionId 等,除了开发难度略增之外,是只有好处没有坏处的。
ellermister
353 天前
@seth19960929
5 分钟的延迟并不能满足常见的需求

比如,假设我登录了一个用户,拿到 jwt token ,此时点击注销,服务端加入黑名单。然后登录过程中 token 泄露或者前端只是选择性从 localstorage 删除,本质意义上服务端还存在。

因为黑名单查询不是即时的,那我就可以在服务端通过改密码方式修改用户的密码,然后重新登录,又可以拿到一个新的 token 。(当然有人会说改密码要二步验证之类的,这是另外一种做法和产品需求范畴了)

> 总之在有效期内仍可以做很多事情,或者不能使其立即下线,就有很多的安全隐患。

有人说你这个强依赖于状态, 不能用无状态做, 那可能确实。但目前的大多数产品提出的需求或者我做过的产品,基础都要满足我所说的即时性。(注销了这个 KEY 就无效了, 在任何层面上他能操作能认证就是一个 BUG )

我看了楼上,思考过确实对用户的系统不适合做 jwt ,只适合真正意义上的无状态需求(下载站鉴权、cdn 鉴权之类的、这些太少了,我基本没接触过)。而只适合所谓第三方鉴权的,服务对 服务之间的鉴权。


虽然我也在用 jwt 、而且每次请求都必命中 redis 查验黑名单,99%请求命中一次数据库。
大部分接口都需要获取用户的自身信息,为什么用户信息不全部存到 jwt ?因为不及时不可靠。

有人说你这样用 jwt 比传统 token 都麻烦,存储的还多几倍的黑名单还基本都要查 redis 、数据库,何必 jwt ,但 jwt 能够方便对接前端及第三方这种共识特性,迫使选择了 jwt 。

总之一句话,我不觉得 jwt 很好,我也觉得一身诟病。我选择 jwt 唯一的技术优势就是它只存黑名单,而传统 token 存白名单。能省点存储就省点吧。
fivesmallq
353 天前
https://jwt.io

JSON Web Token (JWT)
@nothingistrue
QlanQ
353 天前
我是彩笔

如果多端,类似 pc + 小程序 + app + h5 想要统一一种认证方式 jwt 不是唯一选择吗?

如果多服务系统,比如 主站 Java ,活动页 php ,im go 这种,用 session 不是更麻烦吗?
hsfzxjy
353 天前
@nothingistrue 是 JSON Web Token
mxT52CRuqR6o5
353 天前
我十分怀疑你的基于 jwt 的登录业务设计的是否正确
我没看明白强制下线功能为啥可以不是每次请求都请求 redis ,那你咋知道当前的 redis 中的 token_version 是多少
是因为你的强制下线功能不是实时的,会有 5 分钟延迟吗?
mxT52CRuqR6o5
353 天前
@ellermister #23
+1 ,安全的不完全等于完全的不安全,没见过哪家登录系统强制下线还有 5 分钟延迟的,5 分钟足够把账户里的钱偷光了
hongfs
353 天前
@QlanQ JWT 并不是唯一,而且可能会让复杂度变高。我们现在的多端方案,同一个接口(也可以不同接口),带上不同端的 type 过来,因为不同 type 提交的内容存在差异,后端返回的是一个随机生成的 Token ( 40 位字符串)存放于 Redis ,可以做到每个端都可以有一个在线,可以做到当修改密码或者拉黑时全部端都可以一起下线。
mxT52CRuqR6o5
353 天前
人家支付宝微信不比你的系统用户多多了,也没见人家用牺牲安全性的方法(强制踢下线有 5 分钟延迟)去提高系统性能
QlanQ
353 天前
@hongfs 我不太能区分,jwt 和 token 的区别,在我看来原理和作用差不太多,只是说 jwt 有一个标准的规则,
如果有这种黑名单,强制下线的需求,我会将 token 存在 redis 中

然后多端登录,就是 redis ,key 的规则问题了,同样可以实现修改密码登录失效的需求
justfindu
353 天前
@QlanQ 没有什么区别, 因为它叫 JSON Web Token
mmuggle
353 天前
JWT 本身无状态,黑名单功能就是强行有状态了,但是只是针对黑名单 token ,总体来说,还是比传统 token 强一点。
seth19960929
353 天前
@nothingistrue 说的在理

@ellermister 黑名单下线这个问题, 其实是一个取舍问题, 就是如果不能接受刷新 token 这段等待时间的话, 没什么好说的了, 就是每一次查询都走黑名单查询(其实很多系统第一次打开 app 或者重新登录才去校验), JWT 确实能省很多内存
@QlanQ 嗯嗯, token 也是一种方式, 就是随机字符串存到 redis 映射出 uid, 现在说这种存 redis 和 jwt 哪种更好.
@mxT52CRuqR6o5
seth19960929
353 天前
@mxT52CRuqR6o5 你这个话说的, 如果是和钱相关, 那和 JWT 有什么关系, 这时候不应该发短信, 人脸识别一堆校验, 这时候全面风控早就拦截好了, 你用 JWT 做这个事不合适.
seth19960929
353 天前
@QlanQ JWT 只是一个标准, 也是 token 的一种. JWT 黑名单用 redis 存的做法, 大家就会觉得为什么不直接把 token 直接存 redis 里.
@mmuggle 1
hongfs
353 天前
@seth19960929 #36 对大多数业务来说,其实 Redis 的成本也是很低的,比如你计算的 1000W key 那会有 2.4G 的一个内存使用,1000W 又不是一直在线的用户,所以内存的实际占用也是非常小的。即使你的用户在线率非常多,你需要对 Redis 进行集群化的资源成本也是非常低的。

如果非要 JWT ,其实可以做成两阶段的,用户请求先 JWT 验证,然后 sha1 等方式减少存储空间,把 sha1 的值去 redis 里面查。
QlanQ
353 天前
@seth19960929 所以我说我分不清 jwt 和 token ,明明都是一个字符串而已,在我的认知里面,就是一个东西
seth19960929
353 天前
@hongfs 如果 token 有效期一个月, 1000w 肯定有的. 如果是抖音那种日活亿级别的, 那得多少内存存 token
@QlanQ 普通的 token 无任何有效信息, 只是一个唯一值, JWT 的话可以通过 秘钥 从 token 里解析出 uid 之类的, 这样子有些场景只有 uid 就不用查数据库.
daimubai
353 天前
如果存库的话,那确实 jwt 和普通的字符串没区别。因为最终都会查库的,就算不解析 token ,也能在库中查到当前用户的信息

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

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

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

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

© 2021 V2EX