个人前后端分离项目中 token 是怎么处理的

2021-08-16 13:35:25 +08:00
 zxCoder

登陆后后端发一个 token,前端存在 localstorage 里,然后前端的登录状态显示是根据这个 localstorage 里的 token 吗,那这样怎么判断 token 过期了呢,前端也要再存个 token 的有效时间吗?

3532 次点击
所在节点    问与答
29 条回复
seki
2021-08-16 13:36:55 +08:00
后端管理 token 的有效期,给前端提示 token 过期
xuxuxu123
2021-08-16 13:38:43 +08:00
每个请求都带 token,后端接收到请求判断 token 收有效;如果 token 过期,就告诉前端例如返回 401:token 过期,前端在请求的响应拦截器全局判断请求的响应码是不是 401 ;
SniperXu
2021-08-16 13:38:48 +08:00
让接口告诉你有没有过期
dfkjgklfdjg
2021-08-16 13:44:09 +08:00
1:基础款,后端接口拦截判断是否 token 过期,如果过期返回 401,没过期继续业务请求,前端请求拦截器内加判断;
2:基础款 Plus,后端返回 token 之后返回过期时间,前端保存在本地,请求之前先判断是否过期,如过期直接提示,中断请求。
zxCoder
2021-08-16 13:47:18 +08:00
@seki
@xuxuxu123
@SniperXu
@dfkjgklfdjg

那这样岂不是会出现,前端认为 token 有效而展示对应的东西,比如没有登录注册按钮而显示个人信息按钮,但是实际上 token 已经过期了,等到发送新的请求才知道
xuxuxu123
2021-08-16 14:12:30 +08:00
@zxCoder 如果 4 楼还达不到你的要求,那么用 websocket 长连接???链接断开或者后端告知 token 失效就进登录页
csdoker
2021-08-16 14:19:14 +08:00
@zxCoder 现在大多数网站都是这样的,必须要有新请求,前端才知道目前用户的 token 是否过期,实际上这样也没什么大问题
Rocketer
2021-08-16 14:29:22 +08:00
如果是 oauth,一般你申请 token 的时候,返回的数据里就告诉你有效期了。

如果是 jwt,那在 payload 里一般也会记录有效期。

你可以用这些数据在前端控制流程,但永远记住——前端控制是为了帮用户获得一个正常的体验,不要总是进入不可用的页面或者点到不可用的按钮。而不是用来限制用户,禁止他进入某个页面或者点击某个按钮。

前端是不可信的!
erwin985211
2021-08-16 14:44:23 +08:00
@zxCoder 是在不行,你在 localstorage 里面存上过期时间,你前端自己判断是否过期,当然后端也要判断
seki
2021-08-16 14:45:31 +08:00
@zxCoder 看到了会有什么后果呢,其实也没什么后果对吧

每次请求都验证 token 的话,只要有一个请求前端就能知道过期

希望让用户尽快得到过期的提示的话,可以用心跳请求
justfindu
2021-08-16 14:47:20 +08:00
所有的需要授权认证的接口, 都肯定是接口告诉你已经过期, 并且不返回数据给你. 肯定不能是前端控制啊
dfkjgklfdjg
2021-08-16 14:51:53 +08:00
@zxCoder #5,正常来说是这样的,只要用户不操作就会保持 “已登陆”状态,直到他下一次请求操作。

亦或你自己写一个定时器,大概半个小时(自己预估)判断一次 token 状态,可以自己本地判断 token 的过期时间戳,或者用心跳 Ping 后端。
kop1989
2021-08-16 15:26:54 +08:00
在发送新请求之前,页面的业务逻辑是静态的。所以页面其实不需要知道 token 是否过期。(除非你给 token 赋予了本不应 token 负责的业务意义)
XTTX
2021-08-16 15:29:28 +08:00
React 的常规做法: ( session based )
1. context 里做一个 useAuth, useAuth 请求"\auth", 后台判断用户是否登录, 已登录->返回 json:{user:xxx}以及将 session info 做到 cookie 里面。 未登录->后台不返回 user json, 前端的 user===null, 对用户显示没登陆的那一部分
2. context 里面还有一个 useFetch, useFetch 请求"\csrf", 后台返回 csrf token, 前端将 tcsrf token 做到默认的 axios head 里面,做成"authAxios", 用 useFetch 共享给全 app
3. 前端请求后端, 必用 useFetch 提供的 authAxios, authAxios 里包含 cookie 。 这样,后台收到的每个请求都包含 csrf 和 session cookie.
4.后台判断 csrf 是否正确,session 是否过期,过期就返回 cookie max (-1), 前端就会删掉对应的 session cookie.


这是一个比较成熟的做法。 前后端分离的 security 是比较难的,建议多看看成熟的项目。
XTTX
2021-08-16 15:34:45 +08:00
如果有能力的话,建议买 reactsecurity.io 的课程,把整个 jwt 和 session 都弄明白。 大部分的大佬都会建议,能不自己做 auth 就不做, 用第三方。
anguiao
2021-08-16 15:42:02 +08:00
和服务器交互时再判断,我觉得没有什么问题,挺合理的。
Leviathann
2021-08-16 16:08:15 +08:00
就 jwt 吧
自带 expire 字段
Kisesy
2021-08-16 16:28:05 +08:00
打开网站时就主动请求一下
copymaster
2021-08-16 18:33:57 +08:00
给你说说我的方案,用户登录成功之后,把用户信息,过期时间等等一些你觉得有用的信息放到 json 中加密发给前端,这个就是你的 token,再加上一个过期时间,用户请求的时候带上这个 token,后端解密放到 session 或 request 域中
KouShuiYu
2021-08-16 18:34:51 +08:00
我是放到 localstorage 里了
打开网站时先判断一下 token
https://github.com/chenkai0520/vite-template/blob/main/src/main.js#L9-L16

发请求的时候自动带上 token
https://github.com/chenkai0520/vite-template/blob/main/src/api/instance.js#L14-L23

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

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

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

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

© 2021 V2EX