使用 token 不是还是要每次都需要从数据库加载用户信息么和传统 session 有什么区别?

2021-09-13 08:33:40 +08:00
 SystemLight
8790 次点击
所在节点    Java
48 条回复
skypyb
2021-09-13 10:07:03 +08:00
@skypyb #20, 这里上边场景说错了,应该是手动吊销,风控自动下线,权限更改等场景。
如果只是单纯的过期实际上你用啥都行,JWT 里就能存失效时间。用户令牌很明显是不可能只有单纯过期这种场景的。
aoling
2021-09-13 10:13:19 +08:00
JWT 建议还是在服务端带一个状态,特殊情况可以作废 token,不然你只能等待 JWT 的规定过期时间
aboat365
2021-09-13 10:35:28 +08:00
forbreak
2021-09-13 10:35:44 +08:00
本来做的就是一件事,肯定没区别。 但是各种场景适用一下 token 就有优势了, 举例: 分布式场景,如果是传统 session,你还要做 session 共享,麻烦还不太可控。用 token 你本来就是自己去缓存或者库去查询的。也就不存在这个问题。 还有就是:多端使用的时候、作为接口使用时候,各种魔改的情况等等还有很多情况下,如果用 token 魔改起来比较方便,毕竟自己实现的。你还可以做成有状态。各种骚操作,改起来方便很多。
crayygy
2021-09-13 10:37:41 +08:00
可以了解一下 SSO 和 OAuth2,在这种情况下的区别就很大了。
hst001
2021-09-13 10:39:08 +08:00
什么 token session jwt 都是等价的一套机制,没有哪个功能是各方实现不了,用哪个都是一样的,非要选一个,那就看个人或团队偏好
ytmsdy
2021-09-13 11:16:10 +08:00
session 其实算是一种特殊的 token,本地也是有一个叫 SessionId 的信息来标识具体是那个用户的。
lap510200
2021-09-13 11:44:48 +08:00
因为纯无状态的不好搞单点和 token 主动失效,但是兼容性好,app,h5,各平台小程序用一套,session 不行
cyaki
2021-09-13 11:56:49 +08:00
bowser1701
2021-09-13 15:00:49 +08:00
@crayygy OAuth2 等鉴权方式与这里讨论的储存 session 方式是没有关系的,用 OAuth2 鉴权还是需要考虑这里讨论的 session 存储的。
ksc010
2021-09-13 15:22:06 +08:00
你说的 session 应该指的是 sessionid,sessionid 的载体可以有多重
比如放到 cookie,http 头, 或者 url 参数中
一般说的 token 也是一种 sessionid, 会放到 http 头 或者 url 参数汇总

后端根据此“sessionid” 识别具体 session (会话)
cjc2017
2021-09-13 15:32:43 +08:00
@cyaki 好一个取水用水
kingfalse
2021-09-13 18:08:30 +08:00
说白了,就是 session ID 放在 cookie 头还是别的头的问题
qianji201712
2021-09-13 18:13:34 +08:00
其实从目的上来说,都是同一类东西,无非是用于用户合法校验,只不过实现机制不一样罢了,Token 适用性更强,web,app,pc 都可以一套。
至于所说的频繁查询,肯定要做一些优化的(不然每次操作都要去 db 查一遍,没必要这么浪费性能),扔 redis 吧,简单快捷。
p786317875
2021-09-13 18:13:35 +08:00
只能说:Token 可以强化成 Session 的形状,Session 无法退化成 Token 的形状
markgor
2021-09-13 20:47:02 +08:00
我自己的理解,

无状态 token 一般都是根据具体权限进行加密生成出来,接收到的时候解密验证权限,不存在加载用户信息。
比如登陆后的读写操作。
生成 token:md5 ( uid +md5 ( 1+1 ))
前端提交:token,uid (明文)
后台验证:
可读:md5(uid+md5(1)) || md5(uid+md5(2))
读写:md5(uid+md5(2))
*日志要记录就用 uid 就行了。

实际上生成规则还需要加入随机数等的,都是生成时候后端传给前端,后续前端都需要携带这些服务端才能验证,作用时防止被猜到验证规则。

然后还有一种 jwt,
这种直接把参数放入载荷里,传给前端,由于解密需要 key,所以前端是没法解密的,但是后端只需要获取到 jwt 就能解密出来。
一般情况下,你把用户 id,昵称,性别,头像,权限这些丢进去载体,
后端解密后就能直接用了,不存在查数据库。
jwt 加密方式是根据这些参数进行加密的,所以如果前端改了这些参数,加密的结果就会不一样,除非把 key 给碰撞出来了。
*很多文档都说不要把私密信息放载体,但我觉得如果对方能解密出来,那载体放什么已经不重要了。

最后,由于是无状态,那么踢出用户 或限制 不能多端登录类的无法实现,这时候可以配合 redis 做个黑名单功能,后端验证 jwt 前都查一次是否存在 redis 黑名单里,存在里面的就直接返回失败。
jimrok
2021-09-13 21:15:04 +08:00
session 通常在 java 的应用上搞,token 可以跨越多个应用,甚至可以传递进 mq 里鉴权。
jimrok
2021-09-13 21:20:25 +08:00
session 通常是一个登录状态的维护,tcp 的长连接维持,也可以用 cookie 来追踪。token 可以替代密码鉴权来创建 session,所以 token 通常是为了鉴权用,而 session 是为了维护鉴权后的状态。
wunonglin
2021-09-13 21:31:17 +08:00
jwt token != token!!!
jwt token != token!!!
jwt token != token!!!

要说多少次啊。唉
mmdsun
2021-09-13 23:18:12 +08:00
@skypyb jwt 要实现服务端强制下线的功能的话,就要服务端存状态了

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

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

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

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

© 2021 V2EX