refresh_token 和 access_token 到底咋回事儿,几个问题一直搞不懂?

  1. 引入refresh_token 是因为 access_token曝光度高

    看到有人说:对于需要用户登录才能访问的的页面,前端每次访问后端API都要携带access_token(一般放在header中),所以这就会导致access_token的曝光度比较高,不太安全,所以引入了 refresh_token。

    但 access_token 通常不是被前端存放在 local_Storage 中吗? 这都不用谈曝光度,别人打开浏览器开发者工具,随时都拿得到啊

  2. 感觉 access_token 连加密都没必要做

    个人认为,反正 access_token 要放在前端,也就是随便给人看,那只要 access_token 不放什么敏感信息,即便被不法分子拿到了,他也没啥用啊
    因为不法分子拿到token无分是冒充用户身份调用后端API,这个只要后端做了 防重放 和 签名,不法分子就算拿到了token他也很难破这两个点
    所以,感觉 access_token 只要不放敏感信息,连加密都没有必要做
  3. 而有人说,因为refresh_token只是在access_token快过期时才会调用后端API换取新的access_token,曝光度比较低,所以引入了refresh_token!

    首先,个人认为的流程是:
    某次前端调用后端API时,后端告诉前端access_token失效了;
    前端然后拿着之前存在local_storage中的 refresh_token再去后端拿一个新的access_token。

    这样看来,refresh_token 和 access_token 既然都被前端存在 local_storage 中,这曝光度一样样的,没啥区别了,都很容易被不法分子拿到

    而如果我们将refresh_token放在后端,当access_token过期时,后端帮前端拿到它对应的 refresh_token,然后给它个新的access_token。那还不如别要refresh_token了,后端直接给前端新的acces_token就得了呗。

    所以这里我想不通,refresh_token到底有什么意义?而且到处都在说 access_token和refresh_token不要曝光,尤其是refresh_token, 也是真没理解啥意思?

所以引入refresh_token 到底是啥原因 没搞懂

阅读 4.7k
4 个回答

你对“非法用户”的理解有误。

你 F12 打开控制台、从 Network 或 LocalStorage 里把 AccessToken 复制出来,然后自己写个爬虫程序开始疯狂调接口。你这在 OAuth 看来其实是正儿八经的“合法用户” —— 这个 AccessToken 本来就是颁发给“你”的,“你”用这个 AccessToken 也没有访问到超越“你”这个用户权限的数据。“你”用了本就属于你自己的 AccessToken 去调接口,这是再“合法”不过的了。

至于你说你绕开了网站本来的业务逻辑,私自发出了请求,那这不是 OAuth 关心的,也不是 OAuth 能解决的问题。那是你自己业务上的“非法”,不是 OAuth 认为的“非法”。

OAuth 想规避的是中间人或者 CRSF 这种的“非法用户” —— 泄露了本不属于他的 AccessToken。其思路很简单,既然泄露不可避免,那就想办法把泄露的损失降低。于是乎就自然而然想到了缩短 AccessToken 有效期的办法。

想一想现实中是不是也是如此?比如你用网银转账,PIN 只有几分钟甚至几十秒的有效期,即便你的 PIN 被坏人偷看到了,他也只能在很短的时间内才能利用上。

但 AccessToken 变短就带来了新的问题:令牌过期了,可正常用户还在用着,总不能没事儿就让用户重新授权吧?于是乎自然而然想到了增加一个 RefreshToken 的方式。

P.S. RefreshToken 并不是解决 AccessToken 有效期变短带来的副作用的唯一方案,甚至 OAuth 2.0 里专门加粗强调了 “However, you may not need refresh tokens”。

引入双 token 目的就是为了减少用户token过期多次重复登录的问题 和 权限泄露的问题。
比如说很多项目的 access_token 有效期很短,就只有半个小时,那么失效后直接提示登陆过期,让用户重新登录就会出现的很平凡。
而是用 refresh_token 去换取新的 access_tokenrefresh_token 这样对于用户来说就是无感的。refresh_token 是不参与业务的,单纯只是交换新 access_token 的作用。

就比如说你提到的拿到了 accecc_token 发布了n条一模一样的信息来捣乱,这边就是重复请求的拦截了,和 token 的关系就不大了。当然硬要说的话短有效期的 token 也可以起到🤏一点点作用。

个人理解,refresh_token 没啥用处,如果 access_token 快过期时,用户还有操作(即调用接口)的话,服务端直接给当前的 access_token 续期即可。当然,具体还是要看实际场景,比如服务端 token 的实现方式是否支持续期等等,否则还是需要 refresh_token 来无感刷新 access_token,以提升用户体验。

第一个问题你理解的没问题,access_token为了安全,一般都设置了时间,还加密了,就算攻击得到了也没用,access_token 本身也不应该包含一些敏感信息。refresh_token 的存在是为了用户体验,用户不用重新登录,系统可以用 refresh_token 自动获取新的 access_token。refresh_token一般设置的比较长,但是refresh_token只是用来获取新的access_token,不是用来获取资源的,至于你说的 "后端直接给前端新的 access_token",这其实就是没有用 refresh_token 的情况。这种情况下,每次 access_token 过期,用户都要重新登录,这样用户体验不好。 "access_token 的加密问题",你的理解基本没问题。access_token 的加密主要是为了防止信息泄露,而不是防止重放攻击。防止重放攻击要其他的机制,比如 nonce 和 timestamp。"为什么 access_token 的有效期要短",这是为了安全。如果 access_token 的有效期设置的时间长,要是被攻击的人拿到,攻击的人就可以长时间地用它去做其他事情。access_token 和 refresh_token 的设计是一个权衡结果,既要安全,又要用户体验好

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏