使用RxJava的OkHttp3身份验证程序

使用RxJava的OkHttp3身份验证程序,java,android,rx-java,okhttp,Java,Android,Rx Java,Okhttp,我有一个TokenProvider,其方法为: public Observable<Token> authWithRefreshToken() { [...] return makeOAuth2Call(source); } 公共可观察authWithRefreshToken(){ [...] 返回makeOAuth2Call(源); } OkHttp的验证器实现如下所示: @Override public Request authenticate(Route r

我有一个TokenProvider,其方法为:

public Observable<Token> authWithRefreshToken() {
    [...]
    return makeOAuth2Call(source);
}
公共可观察authWithRefreshToken(){
[...]
返回makeOAuth2Call(源);
}
OkHttp的验证器实现如下所示:

@Override
public Request authenticate(Route route, Response response) throws IOException {

    Observable<Token> tokenObservable = tokenProvider.authWithRefreshToken();

    return response.request().newBuilder()
            .header("Authorization", "Bearer " + "HERE_I_HAVE_TO_SET_THE_TOKEN")
            .build();
}
@覆盖
公共请求身份验证(路由、响应)引发IOException{
Observable tokenObservable=tokenProvider.authWithRefreshToken();
返回response.request().newBuilder()
.header(“授权”、“承载人”+“此处\u我\u有\u设置\u令牌”)
.build();
}

基本上,我的问题是:如何把它做好?我可以以某种方式同步接收令牌吗?当然,我可以更改OAuth API,但我只是好奇

搜索了一段时间后,我发现:

@Override
public Request authenticate(Route route, Response response) throws IOException {

    Token tokenObservable = tokenProvider.authWithRefreshToken().toBlocking().first();

    return response.request().newBuilder()
            .header("Authorization", "Bearer " + tokenObservable.getRefresh_token())
            .build();
}
正如
toblock
的文档所述:

将可观察对象转换为BlockingObservable(使用blocking运算符的可观察对象)


由于原始请求已经有了拦截器,您可以检查该拦截器中的响应,并进行同步阻塞调用以刷新令牌

然后您可以重试原始请求

在验证器或拦截器内进行阻塞调用不是一个好主意,但通常可能会起作用。大概是

Response result = chain.proceed(requestWithOldToken);

if (result.code() == 401) {
  String newToken = refreshToken();
  Request requestWithNewToken = ...; 
  result = chain.proceed(requestWithOldToken);
}

return result;
我在我的项目中做了一些非常相似的事情


我建议您在Rx层上执行此操作,而不是在OkHttp层;这将阻止更少的线程,并允许在令牌检索失败时进行f.e.重试。

令牌提供程序.authWithRefreshToken需要多长时间才能完成?与原始请求大致相同,必须予以答复。我有一个带令牌的拦截器,我只想在令牌过期时处理这种情况。啊,是的,这需要同步完成。e、 我错过了,这个,我会更新我的答案