何时用刷新令牌交换访问令牌
Posted
技术标签:
【中文标题】何时用刷新令牌交换访问令牌【英文标题】:When to exchange access token with refresh token 【发布时间】:2019-01-15 10:17:07 【问题描述】:我了解使用 OAuth2 的流程是:
在短期访问令牌过期(服务器返回 401)后,客户端必须使用刷新令牌请求一个新令牌。
要在 ios(使用 AFNetworking)或 android(使用 Volley)应用程序中实现它,我想网络管理器必须能够检测返回的 401 错误,然后向身份验证服务器发送请求。
问题在于网络的并发使用。考虑访问已过期的场景,应用程序发送 2 个请求:req1 和 100 毫秒后,req2。绘制在时间轴上,如下所示:
req1 --> 401 --> (refresh req) --> OK, new access and fresh tokens --> retry req1
req2 --> 401 --> (refresh req) --> 403, wrong refresh token
最终结果是req2会失败,应用会因为403错误退出用户。
所以我的问题是
这个实现是否朝着正确的方向发展?还是收到401后刷新不对?我是否应该在用户启动应用程序时刷新令牌(以减慢应用程序启动为代价)
如何解决并发问题?
【问题讨论】:
你在android中使用哪个库进行api调用?? @ChandrakantDvivedi 我正在使用 Volley 我用的是okHttp,这里提供了拦截器,可以在请求和响应之间进行拦截。 Volley 也可以,问题是如何兑换代币 @Siyu 你是否已经有一些令牌管理器实现,适用于顺序请求但可能会在并行请求上失败? 【参考方案1】:由于您有一个现有的令牌管理器,我会在其中添加一些额外的逻辑(在 Java 中):
class TokenManager
private String accessToken;
private CompletableFuture<String> accessTokenRefreshComletableFuture;
public CompletableFuture<String> getAccessToken()
if (this.accessToken is expired)
// If refreshed accessToken is being requested
CompletableFuture<String> runningRequestFuture = this.accessTokenRefreshComletableFuture;
if (runningRequestFuture == null)
// For thread safety, this assignment should be synchronized (or made atomic)
// with the previous reading
this.accessTokenRefreshComletableFuture = new CompletableFuture<>();
// Request a fresh access token.
// When you get a new access token, set the this.accessTokenRefreshComletableFuture
// complete and remove its reference from the manager class.
return runningRequestFuture;
// Synchronous result
return CompletableFuture.completedFuture(this.accessToken);
管理器不返回访问令牌,而是返回 CompletableFuture(javascript 中的承诺 - 异步结果)。如果需要刷新访问令牌,首先检查/token
端点请求是否已经在运行。如果是,则返回CompletableFuture
。
这样,您将始终拥有一个有效的访问令牌或一个 CompletableFuture
等待新的访问令牌。
【讨论】:
所以想法是在发送任何请求之前检查令牌? 是的,我认为在发送之前检查它是件好事——它更快,并且可以避免太多被禁止的请求访问服务器。但如果您从资源服务器获得 HTTP 403,您应该使用刷新的访问令牌重试。 好的,但是如果我得到了 403,我该如何避免遇到我帖子中描述的情况? 对不起,我的意思是 HTTP 401 - 然后你会得到一个刷新的访问令牌。你不应该得到 HTTP 403 -req1
将要求刷新令牌并等待它返回,req2
将检测到等待刷新的令牌。然后他们都将使用相同的有效访问令牌。
对不起,我对此有点固执,但是如何检测到 req1 正在请求新令牌并阻止 req2?以上是关于何时用刷新令牌交换访问令牌的主要内容,如果未能解决你的问题,请参考以下文章