V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
zxCoder
V2EX  ›  问与答

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

  •  
  •   zxCoder · Aug 16, 2021 · 4058 views
    This topic created in 1719 days ago, the information mentioned may be changed or developed.

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

    29 replies    2021-08-17 17:46:57 +08:00
    seki
        1
    seki  
       Aug 16, 2021
    后端管理 token 的有效期,给前端提示 token 过期
    xuxuxu123
        2
    xuxuxu123  
       Aug 16, 2021
    每个请求都带 token,后端接收到请求判断 token 收有效;如果 token 过期,就告诉前端例如返回 401:token 过期,前端在请求的响应拦截器全局判断请求的响应码是不是 401 ;
    SniperXu
        3
    SniperXu  
       Aug 16, 2021
    让接口告诉你有没有过期
    94
        4
    94  
       Aug 16, 2021   ❤️ 4
    1:基础款,后端接口拦截判断是否 token 过期,如果过期返回 401,没过期继续业务请求,前端请求拦截器内加判断;
    2:基础款 Plus,后端返回 token 之后返回过期时间,前端保存在本地,请求之前先判断是否过期,如过期直接提示,中断请求。
    zxCoder
        5
    zxCoder  
    OP
       Aug 16, 2021
    @seki
    @xuxuxu123
    @SniperXu
    @dfkjgklfdjg

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

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

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

    前端是不可信的!
    erwin985211
        9
    erwin985211  
       Aug 16, 2021
    @zxCoder 是在不行,你在 localstorage 里面存上过期时间,你前端自己判断是否过期,当然后端也要判断
    seki
        10
    seki  
       Aug 16, 2021
    @zxCoder 看到了会有什么后果呢,其实也没什么后果对吧

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

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

    亦或你自己写一个定时器,大概半个小时(自己预估)判断一次 token 状态,可以自己本地判断 token 的过期时间戳,或者用心跳 Ping 后端。
    kop1989
        13
    kop1989  
       Aug 16, 2021
    在发送新请求之前,页面的业务逻辑是静态的。所以页面其实不需要知道 token 是否过期。(除非你给 token 赋予了本不应 token 负责的业务意义)
    XTTX
        14
    XTTX  
       Aug 16, 2021
    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
        15
    XTTX  
       Aug 16, 2021   ❤️ 1
    如果有能力的话,建议买 reactsecurity.io 的课程,把整个 jwt 和 session 都弄明白。 大部分的大佬都会建议,能不自己做 auth 就不做, 用第三方。
    anguiao
        16
    anguiao  
       Aug 16, 2021
    和服务器交互时再判断,我觉得没有什么问题,挺合理的。
    Leviathann
        17
    Leviathann  
       Aug 16, 2021 via iPhone
    就 jwt 吧
    自带 expire 字段
    Kisesy
        18
    Kisesy  
       Aug 16, 2021
    打开网站时就主动请求一下
    copymaster
        19
    copymaster  
       Aug 16, 2021
    给你说说我的方案,用户登录成功之后,把用户信息,过期时间等等一些你觉得有用的信息放到 json 中加密发给前端,这个就是你的 token,再加上一个过期时间,用户请求的时候带上这个 token,后端解密放到 session 或 request 域中
    KouShuiYu
        20
    KouShuiYu  
       Aug 16, 2021
    我是放到 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
    ajaxfunction
        21
    ajaxfunction  
       Aug 16, 2021
    最靠谱的就是 header 里带 token 啊,每次请求要校验 token 状态,
    还有一种 jwt,我一直觉得不好用。
    XTTX
        22
    XTTX  
       Aug 16, 2021
    @ajaxfunction header 带 token, token 可以存在内存里,避开存在 localstorage,就像 csrf token. 登录如果需要 persist, 还是要用到 cookie.
    GG668v26Fd55CP5W
        23
    GG668v26Fd55CP5W  
       Aug 17, 2021 via iPhone
    本地 local storage 也存一个过期时间,请求前先判断是否到期,到期直接转到登录流程,可以少一次 API 请求,同时清除 local storage 的相关数据,比如 token 。

    后端必然要做校验,jwt 本身就要检验过期时间,以防有人恶意提交或者意外提交过期的 token,单返回 401 可能不够,需要补充错误信息,有可能是请求相应资源的权限不够,比如要 VIP 才能取得访问,也可能是用户身份失效。两者处理的逻辑不一样。
    zzl22100048
        24
    zzl22100048  
       Aug 17, 2021 via iPhone
    直接用 oidc 防止不必要的烦恼
    CQCQCQ
        25
    CQCQCQ  
       Aug 17, 2021
    前端:“和服务器交互时再判断是合理的”

    后端:WTF ?
    kekxv
        26
    kekxv  
       Aug 17, 2021 via iPhone
    cookie 有什么问题吗?
    ChangJingli
        27
    ChangJingli  
       Aug 17, 2021
    前端把 token 存在 cookie 里,并设置与后端一致的 expire 时间即可。
    XTTX
        28
    XTTX  
       Aug 17, 2021
    @xliao “前端:“和服务器交互时再判断是合理的”” 这话有啥问题?
    Martin9
        29
    Martin9  
       Aug 17, 2021
    4L 说的对
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2687 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 87ms · UTC 13:20 · PVG 21:20 · LAX 06:20 · JFK 09:20
    ♥ Do have faith in what you're doing.