为什么那么多 web 系统使用 jwt token 来做身份认证

2021-04-29 15:56:52 +08:00
 aboat365

我个人觉得大量的 web 系统在滥用 jwt token 技术。jwt token 签发后可使用私钥来验证其是否过期和篡改,这个技术用来做下载链接、邮箱验证、或短时间内的一次性验证业务是非常好的。但如果用来做 web 系统的身份认证,那简直糟糕透顶。在真正无状态下,很难平衡签发时间和安全之间的矛盾,还有无法续期导致的用户体验问题。当然,可以打补丁,甚至变得有状态,最后解决以上问题。但是,为什么一开始不用 cookie + session 呢?想听听大家的看法。

12360 次点击
所在节点    信息安全
97 条回复
a728976009
2021-04-30 11:16:02 +08:00
@kahlkn #58 阿里云有 oidc 服务的 https://oauth.aliyun.com/.well-known/openid-configuration,Google 更是用了 oidc 很久了,甚至还有一个 playground https://developers.google.com/identity/protocols/oauth2/openid-connect
kahlkn
2021-04-30 11:19:29 +08:00
我们的 分布式 应用场景,就是由 认证授权模块 统一生成一个 类 UUID 的 token,用户登陆成功后,返回给前端,反正前端看着保存呗,别弄丢就行了。 然后每次请求的请求头 都会带有 这个 token,至于多域名跨域问题? 后端配置哪些域名可以进来就好了。

流量 -> 阿里云 LBS -> 业务服务器 Nginx -> 网关 (校验 类 UUID 的 token 是否合法,是否有访问这个接口的权限)-> 业务模块 (获取用户信息工具 根据 token 获取用户信息,并存入 threadlocal )

如果用户信息存入字段,仅仅存入比如用户昵称几个字段,业务上不一定用得到,还得去查一次,如果都存,一些业务的用户信息敏感不敏感先不说,单纯数据量,就很多,上面的 获取用户信息我们设计的也是分段获取,即你要一个用户属性,会自动拉去一定的用户信息到 threadlocal 中,不全部拉去因为多,也不能保证都用到。

是,jwt 是减少了 网关层面的 一次查询,也仅仅是 token 合法性校验的查询 省去了,但是 接口权限 校验还是要查的把。后面业务模块中获取用户信息大概率还是要再查一次的把。所以呢,JWT 最后还是变成了一个 类 session id 的东西。

至于水平扩展,网关受不了了,加机器。业务模块受不了了,加机器。注册中心大概率不会受不了的。 想怎么加就怎么加,只要有钱就行。
lldld
2021-04-30 11:19:37 +08:00
因为 jwt 省钱, 省事.

1) sessionId 的有效验证必须依赖后端查询, jwt 是通过计算来验证, 成本低, 速度快.
2) jwt 可以添加一些不敏感的数据, 前后端都可以使用, 减少了查询, 成本低.

sessionId 更安全, 但是有多少数据需要这么安全呢? 而且需要高安全性的数据和操作可以要求用户提供其他凭证的, 比如支付时提供密码之类.
liuky
2021-04-30 11:20:57 +08:00
最恶心 session, 相比于把 jwt 变成有状态, session 的滥用才是真真让人感觉到恶心的
also24
2021-04-30 11:24:31 +08:00
@GooGee
这篇文章,还有楼主的附言,实际上在对比都不是 JWT 和 session,而是 Client Side Session 和 Sever Side Session,各种所谓的优势劣势,也是这两种形式的 Session 的差异。

而 JWT 在这个场景下,只是作为 Client Side Session 的具体实现和载体而已。

我在之前的帖子里专门说了这件事,比较冗长,但还是建议看一下:
https://www.v2ex.com/t/656457

关于 Session 与 JWT 经常被拿来做对比这件事,也专门做了说明:
https://blog.by24.cn/archives/about-session.html#cl-48
SjwNo1
2021-04-30 11:25:59 +08:00
@a728976009 jwt 有方法可以无状态地实现单点登录吗
h82258652
2021-04-30 11:26:12 +08:00
看需求看场景呗。session id 也是能存数据库的。jwt 性能高,对移动端友好,但做回收不好弄,得像上面说的弄 redis 黑名单之类的方案,就有额外的工程量。
a728976009
2021-04-30 11:30:53 +08:00
@SjwNo1 #66 jwt 不是用来解决 sso 的,它是一种 encode 方式,你需要找的是 oidc,建议搜一下关键字 oidc sso
Slin
2021-04-30 11:32:30 +08:00
@kahlkn 楼主说的 session + cookie 和 JWT 的问题,前面这种方式基本都被淘汰了,JWT 的缺点很明显,其实大部分用 JWT 都没有用无状态特性,只是用来生成一个 token 里面携带了多一些的信息 并没什么不妥。
EIJAM
2021-04-30 11:42:51 +08:00
@zoharSoul 纯好奇,不用 local storage,那移动端用什么存 jwt 的?
falcon05
2021-04-30 11:51:28 +08:00
无状态的 jwt 有很多需求无法满足,比如 revoke,有状态的 jwt 又不如 session 成熟
kahlkn
2021-04-30 11:53:50 +08:00
首先 阿里云 确实有 JWT 的应用,这个让我确实很高兴,毕竟终于见到 JWT 的大厂的应用场景了。就是 @a728976009 说的 oidc 。 https://helpcdn.aliyun.com/document_detail/93698.html

然后 了解了一下 oidc,感觉 OIDC 和 OAuth 的不同,就是 用 JWT (这里的 JWT 指这种机制,毕竟不同的签名 /加密名称不同) 来做了 用户基础信息 的载体(比如 用户 ID 用户名称),用户的其他信息 还是需要 调用接口去取的。然后因为 OIDC/OAuth 都是用来授权,或者三方登陆的,没有普通业务场景那么多问题,直接 JWT 传过去来获取用户信息就好了。

优势,原来 OAuth 需要 先获取到 access_token ,再去调用 接口 获取用户信息。 而 OIDC 直接 返回了 id_token ( JWT ) 和 access_token (可有可无看服务商),对于大部分 只需要 三方的用户 ID 和 用户昵称的 场景,这样一步就够用了。

至于用 JWT 去获取用户信息这个场景,本来服务于三方授权这样一种业务,你不可能说为 access_token 之类的 还设计什么角色、权限、接口权限 之类的 rbac 那套玩意,毕竟三方授权对于调用者来说我仅仅需要该用户在你网站上的部分用户数据。所以 JWT 的方式其实相对来说 优于 类 session id 模式。

而且那些把 JWT 用来业务系统中的一些问题,比如基本上都不会出现。
aboat365
2021-04-30 12:59:12 +08:00
@also24 拜读了你的文章,写的真棒!特别是提出 Client Side Session 和 Sever Side Session,更加精准简洁的描述了本主题中讨论的问题。在文章中,我发现 Sever Side Session 似乎得到更为广泛的支持。但为什么在国内,Client Side Session 模式特别盛行呢(使用如主题附录中 jwt 的实现)?
zoharSoul
2021-04-30 13:04:46 +08:00
@EIJAM #70 sp 啊, sqlite 啊, 等等,
当然这也算广义上的本地存储
wshcdr
2021-04-30 13:40:12 +08:00
无论是 session 还是 jwt 其实就是解决一个问题, 服务端怎么去识别连进来的客户端,session 是 pc 时代的产物,现在移动端盛行了,jwt 更适合了
sherlockwhite
2021-04-30 13:51:55 +08:00
localstorge 是 web 里面的实现吧,到移动端这边,是不支持 cookie 、session 的,因为他不是浏览器,就没有必要非要上 session 。这没什么问题吧
namelosw
2021-04-30 13:59:51 +08:00
我搞过挺多这个,其实我觉得别的因素都是次要的,作为主要原因说不通,主要的因素还是性能 / 横向扩展性。

流量不大的时候我觉得 Session 更简单好用。JWT 实现后续功能的时候基本上都是各种 Hack 。

JWT 流行主要因为 JWT 横向扩展性好,不浪费后端资源。

像 Google 力推 OIDC 这种 SSO 方案思路也类似,目的就是 stateless,这样才比较容易对付亿级的用户。
baiyi
2021-04-30 14:06:19 +08:00
想起了我几年前的提问帖子......《请教各位一个问题, 为什么 session 机制没有被 JWT 所取代?》

现在 JWT 有了更多的使用场景,其实已经有很大的发展了。
aboat365
2021-04-30 14:19:39 +08:00
@baiyi #78 搜索了一下,这就是一个镜像问题😁 https://www.v2ex.com/t/381996
三十年河东三十年河西,现在是 jwt 流行了。
index90
2021-04-30 14:25:18 +08:00
jwt 和 session 的最大区别是去中心化。
现在 web 网站,登录时一个一个站点:account.xxx.com
看视频是一个站点:video.xxx.com
论坛是另一个站点:bbs.xxx.com
如果用 session,那么所有站点都需要对接到一个中心化存储( redis )
如果是 jwt,只需要验证签名就完事了

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

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

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

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

© 2021 V2EX