2016-01-02 39 views
4

在每个请求中拥有有效的IdToken的最佳方式是什么?Retrofit2(拦截器)+ GoogleApiClient如何刷新令牌

我的第一个赌注是一个okhttpclient拦截器,它将令牌添加到每个请求中。但我不知道如何在拦截器内获得有效的令牌。

GoogleApiClient的文档建议在每次获取有效令牌的请求之前调用silentSignIn(GoogleApiClient)。问题是我无法访问拦截器中当前连接的googleapiclient。

回答

0

我最近面临类似的问题,我发现一个不是很漂亮,但工作的解决方案。 你可以使用一个静态变量。

public class SessionData { 

     private static String sessionId; 

    public static String getSessionId() { 
     return sessionId; 
    } 

    public static void setSessionId(String sessionId) { 
     SessionData.sessionId = sessionId; 
    } 
    } 

然后,您可以在从Google SDK获取它(例如用户登录后)后设置IdToken。

SessionData.setSessionId(yourCurrentToken); 

在声明中Retrofit.Builder类,你应该使用下面的进口(如你所说,okhttp拦截器)。

import com.squareup.okhttp.Interceptor; 
import com.squareup.okhttp.OkHttpClient; 
import com.squareup.okhttp.Request; 
import com.squareup.okhttp.Response; 

而且该类的内容应该如下所示。

public class RestClient implements Interceptor { 

    public RestClient() { 

     OkHttpClient httpClient = new OkHttpClient(); 
     // add your other interceptors … 
     // add logging as last interceptor 

     httpClient.interceptors().add(this); // <-- this adds the header with the sessionId to every request 

     Retrofit restAdapter = new Retrofit.Builder() 
       .baseUrl(RestConstants.BASE_URL) 
       .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .client(httpClient) 
       .build(); 
    } 

    @Override 
    public Response intercept(Chain chain) throws IOException { 
     Request originalRequest = chain.request(); 

     if (SessionData.getSessionId() != null) { 
      Request newRequest = originalRequest.newBuilder() 
        .header("sessionId", SessionData.getSessionId()) 
        .build(); 
      return chain.proceed(newRequest); 
     } 
     return chain.proceed(originalRequest); 

    } 
} 
0

GoogleApiClient只是帮助您连接到Auth.GOOGLE_SIGN_IN_API只要你连接,你可以创建多个GoogleApiClient /断开适当他们。在Google的示例中,autoManage配置为在FragmentActivity中使用GoogleApiClient时为您节省锅炉板代码。当你需要在非UI代码中使用它时,假设你在工作线程中。你可以这样做:

private static final GoogleSignInOptions sGso = 
    new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
     .requestIdToken(SERVER_CLIENT_ID) 
     .requestEmail() 
     .build(); 

// In your interceptor code: 
GoogleApiClient apiClient = new GoogleApiClient.Builder(mContext) 
    .addApi(Auth.GOOGLE_SIGN_IN_API, sGso) 
    .build(); 

try { 
    ConnectionResult result = apiClient.blockingConnect(); 
    if (result.isSuccess()) { 
     GoogleSignInResult googleSignInResult = 
      Auth.GoogleSignInApi.silentSignIn(apiClient).await(); 
     if (googleSignInResult.isSuccess) { 
      String idToken = googleSignInResult.getIdToken(); 
      // set to header and pass to your server 
     } 
     ... 
    } 
} finally { 
    apiClient.disconnect(); 
}