为什么需要设置国企 refresh_token 来刷新 access_token,有些人说是因为 Access_token 会过期,refresh_token 也会过期,为什么不设计成 access_token 和 refresh_token 一样长的过期时间,然后 refresh_token 就不需要了,反正 refresh_token 也会过期
1
Rekkles 2018-06-12 17:08:34 +08:00
refresh_token 过期时间比 access_token 要长,这样 access_token 即使过期了,也可以用 refresh_token 去重新刷新 token,既为了安全考虑,也为用户体验着想
|
2
littleylv 2018-06-12 17:12:41 +08:00
如果只是 access_token 过期了,可以继续用 refresh_token 来换取 access_token,换取的过程直接调接口,用户感觉不出来。
一旦 refresh_token 过期,就需要用户重新登录、授权等流程了。 所以 refresh_token 的作用可以理解成,不需要每次 token 过期就需要用户登录授权。 你说的“ refresh_token 就不需要了”完全是不对的 |
3
march1993 2018-06-12 17:20:23 +08:00 via iPhone
我和你有同样的疑问,我觉得 access_token 也没有意义。从安全角度讲,拿到 access_token 离拿到 refresh_token 也只有一步之遥了
|
5
cc959798 OP @littleylv 你好,refresh_token 作作用我清楚,不需要重新登录就可以再次拿到授权,但是如果把 access_token 的过期时间和 refresh_token 一样长的话感觉就不需要 了,毕竟如果一样长的话,access_token 过期了 refresh_token 也过期了,然后重新登录不就行了
至于安全方面我不太明白 refresh_token 的存在的意义 |
6
zhouyou457 2018-06-12 18:21:46 +08:00
refresh_token 是一次性的,同时还需要校验客户端的有效性,比如客户端 secret_key 之类的
|
7
zhouyou457 2018-06-12 18:23:53 +08:00
在我做的系统中 access_token 过期时间是 1 天,而 refresh_token 过期时间是一个月...如果按你说两者同时过期,让用户输入密码的话,使用体验是很差的....至少我不愿意在一个应用中反复输入密码
|
8
littleylv 2018-06-12 18:41:24 +08:00 1
@zhouyou457 #7
也许楼主的意思是:如果他不需要 refresh,然后把 access 设置成很久(比如和你的 refresh 一样一个月),那是不是也是一个月后再让用户登录授权,跟你的系统没两样(看起来没两样)。 但是为了防止 access token 的泄露,一般会把他设置很短时间比如一天。 @march1993 #3 拿到 access 不等于可以拿到 refresh,因为 access 会经常在 api 调用中传输,会有安全隐患,但即使被人拿到了,别人根本不知道 refresh,所以只要几个小时后 access 失效,别人也就没辙了。 这就是为什么需要两者并用,切 access 时间很短的原因了把 |
9
lurenw 2018-06-12 18:57:49 +08:00 1
access_token 暴露在外面的时间越久越危险,需要不断变化来防止泄露。
refresh_token 用专门的接口和单独的服务器,达到相对的 safer。 ps. oauth 和 jwt 那套标准和流程真的啰嗦。 |
10
mooncakejs 2018-06-12 18:59:10 +08:00
refresh_token 的获得和更换 access token 只有 2 个接口,这两个接口需要严格的安全措施( https 等),但是对于 access_token 的使用,没有这个限制,所以泄露风险大大增加。
|
11
maichael 2018-06-12 19:07:46 +08:00 1
There is a security reason, the refresh_token is only ever exchanged with authorization server whereas the access_token is exchanged with resource servers. This mitigates the risk of a long-lived access_token leaking in the "an access token good for an hour, with a refresh token good for a year or good-till-revoked" vs "an access token good-till-revoked without a refresh token."
|
12
maichael 2018-06-12 19:10:16 +08:00
上面忘记加引用了。
大体意思和 #9 差不多。 |
13
march1993 2018-06-12 19:51:58 +08:00 via iPhone
@littleylv 那完全可以授权多个 access_token,独立审计,也比这种短时 access_token 好啊
|
14
Foolt 2018-06-12 20:13:41 +08:00
@march1993 你觉得拿到 access_token 离拿到 refresh_token 也只有一步之遥,是因为你的业务场景比较简单,access_token 和 refresh_token 保存在同一个地方。
有的场景并不是这样。比如说你要开发个 Javascript 版微博,用户授权后,你直接在浏览器用 JS 获取微博内容,那么 access_token 就会暴露在浏览器之中,但 refresh_token 只在你的服务器里,当用户退出网页后你可以通过刷新令已经暴露的令牌失效。 |
15
sidgwick 2018-06-12 20:19:03 +08:00 via iPhone
@littleylv 我也觉得是这样,access token 需要经常在网络上传输。这传来穿去的就不安全了
|
16
march1993 2018-06-12 21:40:50 +08:00 1
@Foolt 这个客户端应该是个第三方 JS 微博客户端对吧?这个短时 access_token 在用户每次登陆时都需要去刷新吧,存不存 refresh_token 一样啊,要 revoke 也可以直接用这个 access_token。所以存这个 refresh_token 的意义在哪里…要安全完全可以隔离不同的 token。客户端如果不安全,拿到了 access_token,那离拿鉴权也不远啊… 所以我不能信服你这个说法
|
17
march1993 2018-06-12 21:44:07 +08:00
当然我觉得拿鉴权还是有点过了,不过如果可以拿到 access_token 一次,就说明可以不断地拿了吧,只要用户经常使用的话?
|
18
chinvo 2018-06-12 21:46:03 +08:00 via iPhone
@march1993 #16 此言差矣
refresh token 必须和 client secret 一起用才有效 而且在权限限制严格的情况下,refresh token 必须在满足特定条件下才会被发放给 oauth client 而 access token 是经常暴露出来的,并且可以先送给第三方 resource provuder,但 refresh token 只能在 oauth client 和 authentication provider 之间传递并且必须被保密存放 |
19
chinvo 2018-06-12 21:51:29 +08:00
@march1993 #16
另外 agent 不等同于 client,agent 是暴露给用户的部分,包括浏览器、app,而 client 是指包含 agent 和执行 code 换 token 或者 refresh token 换 token 的服务器端两部分,单纯的 agent 形式的 client 又叫 public client,是不能使用 client secret 和 refresh token 的 #17 但是非法的 agent 能偷到一次 access token 不代表可以偷到第二次,而如果能偷到 refresh token 并使 refresh token 有效,就是非常严重的安全事故了 |
20
march1993 2018-06-12 21:51:47 +08:00
@chinvo 我觉得这种做法看似加强了安全,实则让审计成了一个黑箱。在若干第三方 resource provider 中,设有一个被入侵污染了,如何发现并清除呢?由于 access_token 是公用的,我任务这种情况下就很麻烦。
|
21
chinvo 2018-06-12 21:52:41 +08:00
feng huang 的 V2EX iOS app 里面误点感谢突然不能取消感谢好尴尬……
|
22
chinvo 2018-06-12 21:54:15 +08:00
@march1993 #20 所以 access token 有效期是短暂的,即使泄露不会造成太大危害,但是如果按你的思路设置为长期,就是很危险的了,尤其是有一些 authentication provider 不支持 revoke access token 的情况下
|
23
march1993 2018-06-12 21:56:49 +08:00
@chinvo 不啊,按照我的思路,我的 token 是独立的,也就是这个 token 能做的事情也是有限的,所以危害是可以控制的。在被污染的 provider 被发现之前,它也可以一直请求更新 token,所以我觉得这个危险可能更严重。
|
25
chinvo 2018-06-12 21:58:57 +08:00
@march1993 #20 抱歉认错了,误认为你是楼主……
access token 被泄漏的时候的安全性保障,来自于短期有效。 另外为了避免 public 的 client (单纯 agent 的 client,包括网页、手机 app )所取得的 access token 泄漏造成麻烦,还引入了 PKCE |
26
chinvo 2018-06-12 21:59:50 +08:00
@march1993 #23 resource provider 并不能更新 token,他只能使用 token 去进行认证或者访问 api,只有 client 能更新 token
|
27
march1993 2018-06-12 22:05:32 +08:00
@chinvo 我理解的短时对于入侵者来说用 access_token 配合预先编写的程序可以干一堆事情了,所以可能我理解上有偏差
|
28
chinvo 2018-06-12 22:16:15 +08:00 1
@march1993 #27 resource provider 的接入一般是受 authentication provider 管理方的严格限制的,所以这个角度不容易泄漏。
大部分只在服务器上调用 RP 接口的 client 也不会泄漏 token。 那么就只剩下 agent 了,而 agent 是不允许持有 client secret 和 refresh token 的。 此时 access token 若泄漏,只会造成短时间的风险(一般是 3600 秒),虽然可以做一堆事,但远比直接泄漏用户密码或者长期令牌要安全的多。 更严格的策略要求 agent 也不可以持有 access token,必须通过后端服务器与 IdP/RP 交互。 在最严格策略下,可能的泄漏风险是换取 access token 之前,authentication provider 返回的 code,引入 PKCE 对 agent 进行 challenge,code 与 PKCE 的 code_verifier 绑定,只有此 agent 的后端服务器可以用 client_secret, code_verifier 和 code 换到 access token。 |
29
SingeeKing 2018-06-12 22:17:51 +08:00
假设 access token 一天过期一次
那么 refresh token 换取 access token 每 24h 只要一次就好了,也就是说每天只有这一次的机会会泄漏 refresh token 而 access token 则会在每一次调用中都可能泄漏,泄漏几率远大于 refresh token --------------- 其实问题来了,如果服务器是 https 的话,那么如果不考虑中间人应该都不会泄漏,而如果被中间人了那么很大几率 refresh token 也保不住(毕竟被中间人攻击的话手机或电脑应该已经被安装了第三方根证书) |
30
chinvo 2018-06-12 22:22:32 +08:00 1
@march1993 另外你 #24 说的没错,通常情况下,token 泄漏,client 的开发者是除用户之外最大的受害者。
所以理论上 client 的开发者有权利和义务选择最严格的流程并且完整实践 OAuth 2.0/OpenId Connect 所有对于安全性的要求和建议。 而对于敏感数据的提供方,作为 RP 应当要求 client 和 IdP 使用严格的 token 交换机制。 作为 IdP,因其本身不提供敏感数据( OAuth 中只作为用户身份认证令牌的提供方,OpenId Connect 中还要提供一个 Userinfo Endpoint ),则应当为 RP 和 client 的安全性考虑,为他们实作标准中提出的安全机制。 |
31
chinvo 2018-06-12 22:24:17 +08:00
@SingeeKing #29 按照 IETF 和 OpenId 的要求,refresh token 和 client secret 是不可以放在 agent 上的,也就是说,其实目前大部分将 refresh token 和 client secret 保存在用户手机或者其他设备的 agent 是不合规且有隐患的。
|
32
SingeeKing 2018-06-12 22:25:27 +08:00
@chinvo #31 What。。Refresh token 不放在客户端怎么刷新。。
|
33
chinvo 2018-06-12 22:26:45 +08:00
|
34
choury 2018-06-12 22:26:47 +08:00
@SingeeKing #29 access token 可以放在 url 里面的,能拿到这个的可能太多了,而 refresh token 只存在自己服务器上,除了和 auth server 交互之外不会被传送
说白了这套流程防的是不怀好意的第三方,并不是用来防开发者的 |
35
choury 2018-06-12 22:28:20 +08:00
@SingeeKing #32 放在客户端,那客户就可以伪造你了……
|
36
ooh 2018-06-12 22:30:49 +08:00
cookie 为什么需要过期?
|
37
q397064399 2018-06-12 22:56:52 +08:00
本身并没有什么卵用,
通信层面上保证安全的是 https 跟非对称加密协议, 客户端层面上是开发者 保证内存不被恶意 dump,token 不被恶意获取 客户端如果保护不了 token 那也同样保护不了 refresh_token 非对称加密要是 证书被恶意篡改 遭受中间人攻击 同样是被脱了裤子, 你捂住了下面,就捂不住上面,也是没有什么卵用 另外 md5 挑战认证,了解一下? |
38
chinvo 2018-06-12 22:59:22 +08:00
@q397064399 #37 所以 refresh token 是禁止放在 agent 的
|
39
q397064399 2018-06-12 23:02:23 +08:00
|
40
chinvo 2018-06-12 23:05:01 +08:00
@q397064399 对的,要用服务器来刷新,客户端和服务器之间没有具体规定,你可以用 access token (由 IdP 颁发而非自行颁发)、cookie、session、或者自行颁发 access token
|
41
q397064399 2018-06-12 23:10:30 +08:00
@chinvo #40
如果刷新 token,还要另外再弄一套认证鉴权机制 我觉得意义就不是很大了,token 跟 refresh_token 的存在 本身就是因为穿了加密协议这条内裤, 假如客户端自己不能保护好 token 跟 refresh_token 那其它的鉴权机制 也无法保证 用户的认证信息 之前 Linus 邮件里面 就批评了那些安全专家, 我觉得 Linus 的观点很正确, 安全的重点从来是人,而不是程序机制,任何机制都无法避免 看守金库的老大爷喝醉之后被小姐骗走钥匙 |
42
march1993 2018-06-12 23:27:35 +08:00
@chinvo 我觉得如果你提 IdP 和 SP 的话属于另外一个范畴了,IdP 和 access_token、refresh_token 解决的是两个不同的问题吧?
|
43
chinvo 2018-06-12 23:28:44 +08:00
@march1993 呃,access_token 和 refresh_token 就是 IdP 发给你( client )的啊
|
44
Foolt 2018-06-13 00:29:24 +08:00 via Android
@march1993
如果只有访问令牌,刷新直接用访问令牌,这意味着用户的访问令牌一旦泄露,黑客可以立即用访问令牌刷新令牌,令你服务器的访问令牌失效,你再想刷新你都刷新不了。这时黑客就可以一直使用访问令牌,直到用户取消授权或者刷新授权。 刷新令牌就是解决这个问题的,刷新令牌长期有效,访问令牌短期有效,就算用户泄露了访问令牌,你服务器也可以通过刷新令其失效,退一步讲,即使没刷新,最多几个小时(一般是一两个小时)就失效了。不会出现用访问令牌刷新,一旦泄露黑客就取代你的情况。 |
45
icz 2018-06-13 08:12:05 +08:00 via iPhone
@chinvo 这么说我怎么觉得 refresh token 放在 agent 上更安全? refresh token 只要不配合 client secret 就是无效的,而 refresh token 相当于是一个临时的用户密码,这样不就相当于在客户端的服务器上明文存用户密码了..?客户端服务器如果被攻破 client secret 和 refresh token 就会一起泄漏。如果 refresh token 放在 agent 上,client 接收 agent 的刷新请求(并用自己的手段认证 agent )再向 oauth 认证服务器请求会不会更好一些?
|
46
catinred 2018-06-13 11:13:59 +08:00
要分两种情况来讨论,不要混淆在一起。1.通讯线路被黑,例如 MITM。2.客户端被破解。
|
47
CoderGeek 2018-06-13 16:03:51 +08:00
refresh_token 未过期 直接申请新的 access_token
refresh_token 过期 重新登录获取授权的 access_token 和 refresh_token |
48
CoderGeek 2018-06-13 16:06:57 +08:00
你要是觉得 OAuth 麻烦 可以用 JWT 简单 或者看看 Apache OAuth2.0 的介绍上面有流程
https://tools.ietf.org/html/rfc6749#section-1.5 |
49
CoderGeek 2018-06-13 16:09:03 +08:00
如果你自己做个开放平台 类似微博 微信 百度 豆瓣 他们都是这样的流程 = = 看他们 授权介绍 ...虽然有的实现很乱
但基本都是按照 OAuth2.0 来的 |
50
mingyun 2018-12-18 22:10:44 +08:00
|
51
JacobAngle 2019-12-03 14:20:37 +08:00
我还是不理解 refresh_token 怎么用才会安全? refresh 请求另一个接口来获取 access_token,那么别人知道 refresh_token 了也就很容易获取到 access_token 了呀?难道是以为别人不知道 refresh_token 的接口?通过分析是很明显就会知道的呀。所以 refresh_token 到底是怎么个安全呢?只是避免在网络传输中被截获?那直接 https 是不是就不会被截获了?那还要 refresh_token 有何用?很迷惑~!
|
52
lubberland666 2020-05-29 18:14:54 +08:00
fuck 深感同意 @JacobAngle 上面有同学说 refresh_token 放在服务端 刷新的时候 需要另外一套鉴权机制来保证刷新过程, 如果一套鉴权机制 需要另外一套鉴权机制来保证安全,那感觉没啥太大意义了
|