2017-01-06 50 views
3

我有方法的TokenProvider:OkHttp3身份驗證與RxJava

public Observable<Token> authWithRefreshToken() { 
    [...] 
    return makeOAuth2Call(source); 
} 

的OkHttp的身份驗證implmentation看起來是這樣的:

@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(); 
} 

基本上,我的問題是:如何做到這一點嗎?我可以以某種方式同步接收令牌嗎?當然,我可以更換我的OAuth API,但我只是好奇。

回答

0

所以尋找了一段時間後,我發現這一點:

@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(); 
} 

由於toBlocking的文件說:

可觀察到BlockingObservable(可觀察到的與封閉運營商)轉換。

+0

'tokenProvider.authWithRefreshToken'需要多少時間才能完成? –

+0

或多或少與原始請求相同,必須予以回覆。 –

0

由於您已經有了原始請求的攔截器,因此您可以檢查該攔截器​​中的響應並進行同步阻塞調用以刷新該令牌。

然後您可以重試原始請求。

在Authenticator或Interceptor中進行阻塞調用不是一個好主意,但通常可能會起作用。所以像

Response result = chain.proceed(requestWithOldToken); 

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

return result; 

我在我的項目中做了非常類似的事情。

https://github.com/yschimke/oksocial/blob/2cdc38f1f6de255846a78b7c9f6747314b733a79/src/main/java/com/baulsupp/oksocial/authenticator/ServiceInterceptor.java#L49

+0

我確實有一個帶有令牌的攔截器,我只想處理這種情況,當令牌過期時。 –

+0

啊,這需要同步完成AFAIK。例如https://github.com/yschimke/oksocial/blob/2cdc38f1f6de255846a78b7c9f6747314b733a79/src/main/java/com/baulsupp/oksocial/authenticator/ServiceInterceptor.java#L49 我錯過了,這個,我會更新我的答案 –

0

,我建議你這樣做的Rx層上,而不是在OkHttp層;這將阻塞較少的線程並允許f.e.重試令牌檢索失敗。