2016-05-21 35 views
8

根據https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInApi.html#constant-summary谷歌總是返回過期的ID令牌(JWT)

如果您使用的ID令牌到期時間,以確定您的會話有效期,你應該檢索刷新ID令牌,通過調用silentSignIn之前,每個API調用您的應用程序服務器。

我想通過調用silentSignIn來獲得新的令牌。但是,我總是收到相同的過期ID令牌。有人可以幫助我指出正確的文檔,說明如何強制刷新以獲取新令牌。我的代碼沒什麼特別的。這幾乎與我們在谷歌樣本中的一樣。

private void buildGoogleApiClient() 
{ 
    // Configure sign-in to request the user's ID, email address, and basic profile. ID and 
    // basic profile are included in DEFAULT_SIGN_IN. 
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
      //.requestServerAuthCode(serverClientId) 
      .requestIdToken(SERVER_ID) 
      .requestScopes(new Scope(Scopes.PLUS_LOGIN)) 
      .requestEmail() 
      .build(); 

    // Build a GoogleApiClient with access to GoogleSignIn.API and the options above. 
    mGoogleApiClient = new GoogleApiClient.Builder(this) 
      .enableAutoManage(this, this) 
      .addApi(Auth.GOOGLE_SIGN_IN_API, gso) 
      .build(); 
} 

我建立我的API如上,當與谷歌按鈕登錄用戶點擊我執行以下操作

OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient); 
     if (opr.isDone()) 
     { 
      // If the user's cached credentials are valid, the OptionalPendingResult will be "done" 
      // and the GoogleSignInResult will be available instantly. 
      Timber.d("Got cached sign-in"); 
      GoogleSignInResult result = opr.get(); 
      handleSignInResult(result); 
     } 
     else 
     { 
      // If the user has not previously signed in on this device or the sign-in has expired, 
      // this asynchronous branch will attempt to sign in the user silently. Cross-device 
      // single sign-on will occur in this branch. 
      Timber.d("Checking if user has already given access to this app on an other device."); 
      showProgressDialog(); 
      opr.setResultCallback(new ResultCallback<GoogleSignInResult>() 
      { 
       @Override 
       public void onResult(GoogleSignInResult googleSignInResult) 
       { 
        hideProgressDialog(); 
        handleSignInResult(googleSignInResult); 
       } 
      }); 
     } 

handleSignInResult方法會得到ID令牌

GoogleSignInAccount acct = result.getSignInAccount(); 
String idToken = acct.getIdToken(); 
Timber.d(acct.getIdToken()); 

編輯1

我有ano相關的問題。

我從https://security.google.com/settings/u/1/security/permissions撤銷權限後,仍然能夠檢索ID令牌(JWT)。假設這個令牌被緩存,並且Android Play服務從本地副本提供它。在令牌過期(60分鐘)後,播放服務應聯繫Google的服務以獲取最新狀態。但是,我沒有看到這種情況發生。事實上,我注意到的另一件奇怪的事情是,當我像大約一天之後調用silentSignIn()時,我得到一個未經用戶同意的新令牌。有人可以測試這個用例並讓我知道輸出。

我該如何確保用戶在被撤銷時再次提供權限。

+0

我不是很確定OptionalPendingResult是如何工作的,但是你在這裏試過指導嗎? https://developers.google.com/identity/sign-in/android/sign-in#start_the_sign-in_flow(最新截至2016年5月17日)。本指南使用'startActivityForResult()'和'onActivityResult()',這是我如何實現我的,它檢索一個未過期的標記。 – Vinnie

+0

哦!我忘了添加startActivityForResult()部分。我也試過這個。但結果沒有變化。你是如何得到未過期的令牌的?谷歌只提供1小時令牌。你是否用類似於https://jwt.io/的方式解碼了智威湯遜?什麼是「exp」時代價值? –

+0

我使用了這裏描述的Google令牌端點。 https://developers.google.com/identity/sign-in/android/backend-authI會將其作爲解決方案寫入。 – Vinnie

回答

1

您將需要使用startActivityForResult(),然後處理登錄結果onActivityResult(),如此處所述Integrating Google Sign-In into Your Android App。然後,要驗證令牌的真實性,請參閱Google的Google登錄Android版指南,以瞭解如何使用Authenticate with a backend server

一個簡單的方法是將令牌傳遞給Google tokeninfo端點 https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123其中XYZ123是您的令牌。