man*_*eak 5 android oauth-2.0 rx-java retrofit2 refresh-token
我有一个应用程序,它使用 OAuth2 进行身份验证并使用 Retrofit 从 RESTful 服务中获取数据。现在,我有令牌检索并刷新并运行。令牌像这样刷新(省略了调度程序):
// Each Retrofit call observable is "wrapper" using this method
protected <T> Observable<T> wrap(@NonNull final Observable<T> page) {
return authenticate()
.concatMap(token -> page)
.onErrorResumeNext(throwable -> {
Log.w(TAG, "wrap: ErrorResumeNext", throwable);
return refreshAccessToken()
.flatMap(accessToken -> page);
}));
}
// Retrieves the access token if necessary
Observable<AccessToken> authenticate() {
// Already have token
if(accessToken != null) return Observable.just(accessToken);
// No token yet, fetch it
return api.getAccessToken(...);
}
// Refreshes the token
Observable<AccessToken> refreshAccessToken() {
return api.refreshToken(...);
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,但在某些情况下,一次发送多个请求并且它们都调用刷新过程 - 基本上我的应用程序最终刷新令牌的次数与当前请求的次数相同。
所以,问题是:我如何确保当需要刷新令牌时,只执行一次,无论有多少正在进行的请求需要刷新令牌?我能否以某种方式让其他请求“等待”直到第一个请求成功调用并检索到新令牌?
我们使用热可观察来完成此行为,用于刷新令牌并为所有无法验证的请求提供对其实例的访问。
使用share
运算符将用于刷新令牌的基本冷可观察值转换为热可观察值,以便所有其他订阅者共享其结果。一旦请求返回,所有等待的观察者都会收到通知,并在那一刻(在操作符链中,它恰好在share()
回调之前doOnUnsubscribe
)销毁刷新的可观察实例,以便下一个订阅者将创建新的可观察实例。所有这些都可以通过单例模式轻松实现,在该模式中,您将刷新的可观察量包装到单例包装类中,然后只需通过 getInstance() 来请求它。如果没有正在进行的请求——实例为空—— getInstance 应该创建一个新实例。
您还需要注意其他一些事情,例如刷新期间的错误和使令牌一起失效,但这些是基础知识。
我现在没有太多时间详细说明这一点,但如果您自己实现此操作时遇到一些问题,请发表评论,我将在明天之前发布一些代码示例。如果没有上下文,它们就没有多大意义。
归档时间: |
|
查看次数: |
1123 次 |
最近记录: |