V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
MingLovesLife
V2EX  ›  程序员

不懂就问,请教一下前端无感刷新 token 到底有没有意义?

  •  
  •   MingLovesLife · 1 天前 · 5794 次点击
    在技术网站看到过无数次前端无感刷新 token 的文章,一直很费解,为啥要刷新 token 呢?那前端给 token 刷新了,token 还有啥意义呢?

    文章给出的原因是,用户正操作着呢,token 突然过期,跳登录页用户体验不好。

    实现步骤:
    accessToken 简称 at ,refreshToken 简称 rt
    1. rt 有效期长,at 有效期短
    2. at 过期了拿 rt 换 at ,重新请求

    疑问:
    1. 既然 rt 长期有效,直接用 rt 有啥问题
    2. 如果从安全考虑,rt 被抓包拿了,也没辙呀
    3. 既然后端知道用户操作了,如果是非异常操作,就自动给 token 延时行不?

    不知道该方案具体是为了什么,还请大神们赐教。希望接到类似需求老哥们聊聊

    PS:轻喷,心平气和
    第 1 条附言  ·  1 天前
    感觉大家的解答,目前出现了两个能说服我的理由(也是自己总结,不知对错,可以修正)
    1. rt 无法访问资源服务器,at 无法访问用户服务器,给抓包、攻击提高了复杂度
    2. 资源服务器可以直接解析 at ,仅在 at 过期后才访问用户服务器,缓解了用户服务器的压力

    产生了新的疑问:
    有几位提到了 at 不可修改,所以一般有效期设置的较短,那么
    1. 当用户修改了账号密码时,会主动通知资源服务器 at 过期了吗?
    2. 我不知道 1 的答案,所以先假设不通知,那该怎么办呢?
    67 条回复    2025-01-07 16:23:12 +08:00
    qhd1988
        1
    qhd1988  
       1 天前
    我觉得只是增加抓包难度罢了,提升用户体验只是带来的"副作用",
    安全不安全,主要看你项目有没有真金白银的价值,有的话,管你啥 refresh_token 还是啥,分分钟给你抓出来
    neptuno
        2
    neptuno  
       1 天前   ❤️ 3
    这么一说确实有道理的,小厂反正无所谓怎么搞都行。大厂的话我的理解就是 refreshToken 可以多一道控制,accessToken 签出之后无法控制失效(除非加黑名单),但 refreshToken 可以控制下一次 accessToken
    wzj92712
        3
    wzj92712  
       1 天前
    这一切的前提是 HTTPS.
    如果有 HTTPS.可以保证你只会被重放攻击.不会真正泄漏 token 的值.

    1.小项目这样做没问题. 只不过如果 rt 可以请求资源. 那就是说可能会被一直重放攻击. 如果 rt 只能换 at.at 过期了.他就不能重放了(他得再次抓包). 安全一丢丢.
    2.基于前提.rt 不会被获取值的.
    3.可行但怪麻烦的,不如直接用长期 token

    个人的理解.不一定完全正确.
    lidashuang
        4
    lidashuang  
       1 天前
    refreshToken 不能访问资源啊
    lidashuang
        5
    lidashuang  
       1 天前
    accessToken 有效期短一点,相对安全一点
    jifengg
        6
    jifengg  
       1 天前
    我以前碰到的时候思考的,不一定对:“服务器端校验 refreshtoken 消耗的资源比 accesstoken 大。”
    更深的原因就没有细究了。
    635925926
        7
    635925926  
       1 天前
    我也无法理解为啥要 jwt ,短短的 token 不香吗
    unlimitedsola
        8
    unlimitedsola  
       1 天前   ❤️ 1
    Access Token 可能是 JWT, 服务端收到时可以通过校验签名来确认是否有效, 不一定需要查询数据库或做完整的校验. JWT 弊端是签出后无法轻松控制失效, 所以需要 Refresh Token 来弥补.
    firstmetcs
        9
    firstmetcs  
       1 天前   ❤️ 1
    我理解的每个请求都有 access_token 的传递,但是只有登录、刷新 token 等操作才会传递 refresh_token ,这样的话 refresh_token 被抓包的几率小多了,然后 access_token 泄露的话那么下次过期自然被抓包的那次就不能再使用了
    ScepterZ
        10
    ScepterZ  
       1 天前   ❤️ 1
    2 、rt 一般会存数据库,所以有办法踢,at 可以接受不能踢,有效期可以很短
    InkStone
        11
    InkStone  
       1 天前   ❤️ 1
    @wzj92712 https 不能重发的。高版本 tls 如果没对握手信息做记录,会话结束后,你拿着私钥都没法把流量解密。更不要说重放了。
    这种我理解更多还是防 XSS 。
    maichael
        12
    maichael  
       1 天前
    1. refreshToken 不应该能访问资源服务器,简单来说 RT 和 AT 访问的“服务器”都是不一样的。
    2. 这是防中间人的问题,跟是否使用 RT&AT 方案无关,这是 HTTPS 等方案的事。
    3. 不行,跟 1 同理,AT 和 RT 是访问不同服务器的钥匙,你有 AT 不代表你有 RT ;抛开权限不同这点,如果后端实现了自动刷新,那就相当于 AT 和 RT 合一,又回到了单一 token 的方案了。

    延伸谈一下,AT&RT 与单 Token 的方案最大的区别是把“获取授权”跟“获取资源”两个行为彻底分离,前者是一个高危害低频率的行为,后者是一个低危害高频率的行为(这里的危害是指 Token 泄漏后带来的影响);越高频率就意味着越高的暴露风险,所以对于高危害的行为,单独出来放在一个低出现频率的 Token 能提高安全性。
    ttimasdf
        13
    ttimasdf  
       1 天前
    不负责任的盲猜一下,没有开发经验纯盲猜啊

    弄个有效期短的临时 ak ,对热缓存和集群部署更友好,token 表直接放内存里面弄个 kv cache 查,肯定比每次请求查用户表去校验 ak ,性能更高一点,只有 refresh token 换 ak 的时候,才需要查一下用户表,验证一下 refresh token 是否有效。
    lambdaq
        14
    lambdaq  
       1 天前
    放弃 jwt 直接全部服务器存状态吧。
    follower
        15
    follower  
       1 天前
    这玩意是用来单点登录的
    双 token 方案既减轻了服务器压力,又对用户的登录态具有一定的控制,其实是个折中的方案
    cat
        16
    cat  
       1 天前   ❤️ 1
    @maichael 换句话说,就是用 RT 代替了账号密码,如果每次请求都携带账号密码,则暴露的风险更高
    johnnyNg
        17
    johnnyNg  
       1 天前
    看看腾讯云,token 过期,直接弹窗登录就好了,不用跳到登录页面
    SilentRhythm
        18
    SilentRhythm  
       1 天前
    at:一般是 jwt ,无状态服务颁发后后端无法控制,而且承载实际权限,所以为了安全,设计有效时间一般较短
    rt:at 有效期短势必需要刷新了,那么刷新 ak 有哪些方案可选?:
    1. at 刷新 at:那我还不如直接长有效时间 at ,安全考虑,不成立;
    2. username/password 刷新 at:username/password 手动输入体验就差,存放在 local-stroage 又太危险了;
    3. rt:折中方案
    myderr
        19
    myderr  
       1 天前
    这个是一个折中方案,jwt 是无状态的嘛,如果签了一个很长的 at,那么这个用户就无法控制( ban )了。但是有个 rt ,那么类似于多久让前端主动请求一下用户状态。
    purringpal
        20
    purringpal  
       1 天前 via iPhone
    增加操作空间吧,如果后端什么监控和防护措施都没有,那就是脱裤子放屁,去你所说 rt 被抓包了等于密码泄露。但是如果加了防护措施可以规避异常访问,用的来说就是在用户体验与安全性的折中做法。。
    purringpal
        21
    purringpal  
       1 天前 via iPhone
    @purringpal 错别字: 如你所说、总的来说
    xiangyuecn
        22
    xiangyuecn  
       1 天前
    以前应该很香,现在看应该算是裹脚布 又长又臭
    w4n9hu1
        23
    w4n9hu1  
       1 天前
    这是为了缓解 OAuth2 在实际应用中的一个主要缺陷,通常访问令牌一旦发放,除非超过了令牌中的有效期,否则很难(需要付出较大代价)有其他方式让它失效,所以访问令牌的时效性一般设计的比较短,譬如几个小时,如果还需要继续用,那就定期用刷新令牌去更新,授权服务器就可以在更新过程中决定是否还要继续给予授权。 -- 凤凰架构
    XCFOX
        24
    XCFOX  
       1 天前   ❤️ 16
    accessToken 、refreshToken 双 Token 只在分布式|微服务架构下有意义。

    考虑我们有用户微服务和订单微服务,我们把用户信息存储在用户微服务,向订单微服务发起请求时需要验证用户有效性:
    1. 如果使用单 token 方案,订单微服务接到请求时 需要向用户微服务发起询问来验证用户有效性,在这一步至少需要一次网络通信。
    2. 如果使用双 token 方案,向用户微服务发起请求时携带 refreshToken ,向订单微服务发起请求时携带 accessToken ,accessToken 过期时向用户微服务发起请求重写签发 accessToken 。
    accessToken 具有以下特性:
    · 明文:这允许订单微服务直接从 accessToken 读取用户信息而不必询问用户微服务;
    · 具备签名:这允许订单微服务直接验证 accessToken 的有效性而不必询问用户微服务;
    · 不可篡改:这使得 accessToken 一经用户微服务签发则在有效期内一直有效,当用户更改密码或其他需要重制登录状态的时候 accessToken 也不受影响,为了满足重制登录状态的需求 accessToken 的有效期一般比较短。
    总结一下,双 token 方案使得订单微服务微服务不用向用户微服务发起询问,代价是 accessToken 不可篡改、登录状态难以清除。

    回答楼主的问题:
    1. refreshToken 只能向用户微服务发起请求,订单微服务无法验证 refreshToken 的有效性;

    2. 是的;

    3. accessToken 不可篡改,不可延时;

    个人看法:双 token 方案带来的「无需向认证服务询问」的特性有一点点优势;但很多场景会有下「踢出用户」的需求,这时候使用双 token 要么等着 accessToken 过期,要么向认证服务发起询问,前者实时性低,后者让损失了 双 token 方案唯一的优势。我的建议是摒弃双 token 方案,使用单 token 存 redis ,认证服务和业务服务都直接从 redis 读取用户状态。
    wu67
        25
    wu67  
       1 天前
    讲真, 我觉得还不如那个脱裤子放屁的操作: 加一道 redis 检验, 判断应该 401 还是正常使用, 既使用了 jwt 的简单粗暴, 又成功把部分数据库压力转移到内存去.
    coderlxm
        26
    coderlxm  
       1 天前 via Android
    这个话题展开讲的话内容太多了,简单说就是一切还是要回归到你的业务需求上,rt 存在本身肯定是有意义的
    jonsmith
        27
    jonsmith  
       1 天前
    安全性考虑,在 JWT 场景,at 有效期不能太久,因为无法踢掉。rt 重新签发,能做一些安全校验。
    sikuu2al
        28
    sikuu2al  
       1 天前
    去年实习的时候有在掘金提过类似的问题,也是关于双 token 的意义的。实习公司做的小项目也要上双 token ,到现在仍旧没有一个能够彻底说服我的理由。
    keakon
        29
    keakon  
       1 天前
    类 JWT 场景下,at 是用签名来验证,而不用实际比对数据库。当发生某些需要 revoke token 的场景时,如果 at 的有效期足够短,可以不实现。等到过期校验 rt 时,发现不可用了,再进行退出。
    sampeng
        30
    sampeng  
       1 天前
    所有用无限期的 token 的时候都一定有过临时 token 。比如后台某个服务/脚本临时用个 token 。。然后时间长了,这个 token 就无法改了,特别的蛋疼。token 就应该是无状态的,一定时间内轮换。不然请用 cookie/session 机制。
    sampeng
        31
    sampeng  
       1 天前
    另一方面。我就在我之前公司 app 上碰到过。无聊的黑客,登陆了就拿着 token 无限制的做任何事。等你发现的时候已经受损失了。如果是双 token 机制,上线的时候就会把访问频率考虑进去。单 token 的,大部分程序员应该实现的就是又不是不能用策略。。防刷?想啥呢。。。
    shenyuzhi
        32
    shenyuzhi  
       1 天前 via iPhone
    纯粹就是为了性能,和安全性/分布式什么的一点关系都没有。
    at 是离线校验,不读数据库。
    rt 是在线校验,需要访问数据库。
    假设某种业务每个小时访问接口 1000 次,at 有效期 1 个小时。此时每个小时可以省 999 次访问数据库。只有过期的那次才需要刷一下
    SilentRhythm
        33
    SilentRhythm  
       1 天前
    针对新的疑问:
    1. 不通知;
    2. 只能等待过期,所以才设计较短的有效期来一定程度上规避安全风险。
    ilylx2008
        34
    ilylx2008  
       1 天前
    看到一个银行的实现,accessToken 有效期 2 分钟
    GooMS
        35
    GooMS  
       1 天前
    小业务规模上,直接签一年的
    crysislinux
        36
    crysislinux  
       1 天前 via Android   ❤️ 1
    refreshToken 我的看法是只是给 jwt 打个补丁,jwt 这东西它就不适合用来做用户登录。用户登录还是老老实实用 session 吧。
    Nazz
        37
    Nazz  
       1 天前 via Android
    鉴权方案有很多种,JWT 属于很辣鸡的那类。云厂商喜欢用 api_key 标识账户,api_secret 对参数签名,生成一次性的 token
    Jtyczc
        38
    Jtyczc  
       1 天前 via Android
    acessToken 用来感知用户是否在线
    SenLief
        39
    SenLief  
       1 天前
    jwt 只是鉴权方案的一种形式,也不一定要用。
    tairan2006
        40
    tairan2006  
       22 小时 22 分钟前 via Android
    无意义,直接用服务端 token ,jwt 只适合一次性授权
    webcape233
        41
    webcape233  
       22 小时 20 分钟前 via iPhone
    tls + cookie 不香吗
    ArianX
        42
    ArianX  
       22 小时 1 分钟前
    refreshToken ,认证应该可以结合一些签名、特征校验吧,比如 refreshToken 只在一台设备、一个地址生效?
    wangtian2020
        43
    wangtian2020  
       21 小时 36 分钟前
    为了假装自己的系统很有价值会被人挟持 token
    accelerator1
        44
    accelerator1  
       21 小时 1 分钟前
    这种双 token 对应的基本是 oauth2.0 ,查一下 oauth2.0 中对于这两个 token 的定义就明白了。

    使用双 token 主要是为了防止 token 泄漏导致的安全问题。at 泄漏,一般两小时就过期了,风险可控; rt 泄漏,过期时间很长,所以一般不会频繁使用。

    前端使用双 token ,主要的泄漏途径就是网络传输层面,被抓包了很容易拿到你的 token ,所以使用 at 减少风险;至于 xss ,目前主流的认证方式都没啥用。。。

    当然,国内的认证服务基本不是完全基于 jwt ,都是有状态的,吊销 at 、rt 很容易,这样的场景下,是不是双 token 没啥区别了。
    flytsuki
        45
    flytsuki  
       21 小时 1 分钟前
    我们小公司直接 token 存 redis,方便登录后踢掉上一个登录状态
    accelerator1
        46
    accelerator1  
       20 小时 58 分钟前
    @webcape233 不香,现在浏览器基本默认禁止跨域携带 cookie 了,做页面嵌套基本会死,特别是内网环境没有固定域名的情况下。
    aloxaf
        47
    aloxaf  
       20 小时 14 分钟前
    最能说服我的理由是——你不信任使用 at 的客户端。

    比如第三方提供的集成服务,我不希望它能拿到有效期很长的 at 。短 at + 长 rt 就能确保用户不使用服务后它能迅速失去对用户资料的访问权。
    samnya
        48
    samnya  
       20 小时 7 分钟前 via iPhone   ❤️ 4
    根据 accessToken 能被泄漏的理论,我觉得他既然能抓取到 token ,也能够直接篡改返回值。
    那么直接把用户的响应改成 401 ,客户端就会立刻触发刷新 token 流程,此时就获得了 refreshToken
    2han9wen71an
        49
    2han9wen71an  
       20 小时 3 分钟前
    我们公司的 rt 和浏览器指纹还有用户 Ip 绑定,不一致就失效。
    另外 at 的用途:
    1. 用户及时下线,at 一般是 15 分钟,rt 是一个星期
    2. 减少用户访问 rt 的次数,一般 rt 放数据库做鉴权,实际上就是账号加密码
    canvascat
        50
    canvascat  
       19 小时 40 分钟前
    之前加了双 token ,去年又去掉了
    clocean
        51
    clocean  
       19 小时 35 分钟前
    斗鱼直播是不是使用了这个技术?反正作为用户来说,体验无敌,登录一次之后就没登录过了
    telemsg
        52
    telemsg  
       19 小时 30 分钟前
    1. 既然 rt 长期有效,直接用 rt 有啥问题
    2. 如果从安全考虑,rt 被抓包拿了,也没辙呀
    3. 既然后端知道用户操作了,如果是非异常操作,就自动给 token 延时行不?

    1 ) rt 过期了咋办? 重新登陆微信? rt+at 能灵活控制过期时间 ( rt 还能 revoke )
    2 )对。 什么技术抓包也没有办法。 尽量 https
    3) 自动延时? 什么情况触发? 我开发业务还需要关心? 你们在网关配置好,我业务开发可不管 (分离)
    abc1310054026
        53
    abc1310054026  
       19 小时 25 分钟前
    @accelerator1 过滤掉跨域的 cookie 是正确的。当然你可以设置 cookie 跨域共享。
    telemsg
        54
    telemsg  
       19 小时 8 分钟前
    产生了新的疑问:
    有几位提到了 at 不可修改,所以一般有效期设置的较短,那么
    1. 当用户修改了账号密码时,会主动通知资源服务器 at 过期了吗?
    2. 我不知道 1 的答案,所以先假设不通知,那该怎么办呢?

    1 )通知了也没有用,at 就是无状态的,所以尽量是配置较短的时间
    这里延伸出另一个问题: 如何做单点退出? (简单来说就是要清理 client token, at 本身还是有效的)
    leokun
        55
    leokun  
       19 小时 2 分钟前
    听了大家的回答,我认为 accessToken 是给 refreshToken 打补丁的
    refreshToken 每次都会访问用户数据库,accessToken 不需要。
    所以 accessToken 本质上是 refreshToken 的离线存储,保证一段时间内不需要再次访问数据库
    leokun
        56
    leokun  
       19 小时 1 分钟前
    @leokun 前面提到 refreshToken 是给 accessToken 打补丁,我觉得说反了
    cat
        57
    cat  
       19 小时 1 分钟前   ❤️ 1
    @samnya 卧槽牛逼!新思路!
    635925926
        58
    635925926  
       18 小时 43 分钟前
    @shenyuzhi 现在单 token 基本存 redis ,也不存在什么性能问题啊
    635925926
        59
    635925926  
       18 小时 38 分钟前
    @samnya 直接抓 rt ,在 pre-post 中每次获取最新 at 不是更爽
    byte10
        60
    byte10  
       18 小时 38 分钟前
    回答其中一点,JWT 是无状态的,去中心化,无法踢出。所有很多大聪明就会加一个 redis 存起来,来判断是否过期 就扔掉,也就是说单纯脱裤子放屁。
    Alliot
        61
    Alliot  
       18 小时 28 分钟前
    accessToken 用来真正的访问资源, 它通常是无状态的 JWT , 带有时间戳,过期时间短。

    refreshToken 一般在服务端有存(方便吊销),过期时间长

    这样的好处是,用户的访问直接使用 accessToken, 这样不会每次都需要访问服务端鉴权,可以降低服务端压力。


    比如 accessToekn 30s 过期,那鉴权部分就从每次请求都鉴权-> 变成了 30s 才访问一次鉴权续期

    降低了服务端压力
    zorui
        62
    zorui  
       18 小时 25 分钟前
    @635925926 使用 jwt 服务端不需要存储, 只需要算法验证, 短短的 token ,要么服务端存储,要么搞一套新的算法规则 还不如 jwt 呢。jwt 最大优势就是只需要算法验证验证就行。
    dogfeet
        63
    dogfeet  
       18 小时 15 分钟前
    对于我们这种游戏业务,只允许单客户端登录的,有很重要的意义。

    1. rt 的存在,就是为了减少核心认证数据的传输频率(比如账号密码,手机验证码等)
    2. rt 会持久化,at 的校验成本更低,往往会存在内存中直接校验。
    3. rt 无法用来登录,只能用来刷新 at ,重点是一个账户只有唯一的一个有效 rt ,每次刷新都需要当前正确的 rt ,刷新后 rt 会变,之前的 rt 就失效了。如果所谓的 rt 被抓包拿了,除非只有你一个人用,否则,用户刷新失败触发账号密码或验证码登录,此时刷新的 rt 会覆盖掉抓包拿的 rt 。也就是游戏中的发现自己被挤下来后,自己用最高优先级的账号密码登录,对方就无法再登录了。

    重点:
    rt 只能使用一次,这是与账户密码最大的不同点。
    rt 只能使用一次,这也是与 at 最大的不同点,成本较 at 高。

    总结:
    正常用户的使用过程中,几乎很少触发账户密码验证码登录,体验更好。
    非正常使用过程中,也能一定程度的保证安全。
    减少账户密码的传输频率也能降低其被窃取的风险。
    635925926
        64
    635925926  
       16 小时 50 分钟前
    @zorui jwt 无状态,不储存,无法被控制。反而是缺陷。
    sardina
        65
    sardina  
       16 小时 16 分钟前
    你说的这种不用 rt 直接把 at 刷新也可以实现无感刷新这种双 token 主要还是用在 oauth2 里,第三方应用申请一个 rt ,然后用 rt 去申请 at ,at 有过期时间,过期了用 rt 去重新获取
    这里有一篇文章可以学习学习 https://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
    meteora0tkvo
        66
    meteora0tkvo  
       15 小时 27 分钟前
    单纯是后端懒得写自动延长 token 有效期的业务,所以交给前端来调取憋屈的“刷新 token”接口
    dengkj
        67
    dengkj  
       13 小时 48 分钟前
    设计两个 token 主要是为了平衡安全性和便利性。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1030 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 77ms · UTC 22:11 · PVG 06:11 · LAX 14:11 · JFK 17:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.