對於僅進行身份驗證的用戶登錄方案,我們建議使用較新的 Google 登錄和Android 本機Web應用程序的一鍵式按鈕。

從GoogleAuthUtil和Plus.API遷移

如果您以前使用GoogleAuthUtil.getTokenPlus.API與Google Sign-In集成,則應遷移到最新的Sign-In API,以提高安全性和更好的用戶體驗。

從訪問令牌反模式遷移

您不應該將通過GoogleAuthUtil.getToken獲得的訪問令牌作為身份聲明發送到後端服務器,因為您無法輕鬆地驗證令牌是否已發佈到後端,從而容易受到攻擊者的訪問令牌的插入。

例如,如果您的Android代碼類似於以下示例,則應將您的應用遷移到當前的最佳做法。

Android代碼

在示例中,訪問令牌請求使用oauth2:加上範圍字符串作為GoogleAuthUtil.getToken調用的scope參數( oauth2:https://www.googleapis.com/auth/plus.login )。

代替使用通過GoogleAuthUtil.getToken獲取的訪問令牌進行身份驗證,請使用ID令牌流或auth代碼流。

遷移到ID令牌流

如果您只需要用戶的ID,電子郵件地址,名稱或個人資料圖片URL,則使用ID令牌流

要遷移到ID令牌流,請進行以下更改:

Android客戶端

  • 如果您請求,請刪除GET_ACCOUNTS (聯繫人)權限
  • Auth.GOOGLE_SIGN_IN_APIGoogleSignInOptions.Builder.requestIdToken(...) GoogleAuthUtilPlus.APIAccountPicker.newChooseAccountIntent()AccountManager.newChooseAccountIntent() Auth.GOOGLE_SIGN_IN_APIGoogleSignInOptions.Builder.requestIdToken(...)

服務器端

遷移到服務器身份驗證代碼流

如果您的服務器需要訪問其他Google API,例如Google Drive,Youtube或Contacts,請使用服務器身份驗證代碼流

要遷移到服務器身份驗證代碼流,請進行以下更改:

Android客戶端

  • 如果您請求,請刪除GET_ACCOUNTS (聯繫人)權限
  • 使用GoogleSignInOptions.Builder.requestServerAuthCode(...)配置將使用GoogleAuthUtilPlus.APIAccountPicker.newChooseAccountIntent()AccountManager.newChooseAccountIntent()任何代碼切換到Auth.GOOGLE_SIGN_IN_API

服務器端

您仍然可以在新舊端點之間共享API訪問邏輯。例如:

GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(...);
String accessToken = tokenResponse.getAccessToken();
String refreshToken = tokenResponse.getRefreshToken();
Long expiresInSeconds = tokenResponse.getExpiresInSeconds();

// Shared by your old and new implementation, old endpoint can pass null for refreshToken
private void driveAccess(String refreshToken, String accessToken, Long expiresInSeconds) {
   GoogleCredential credential = new GoogleCredential.Builder()
           .setTransPort(...)
           ...
           .build();
   credential.setAccessToken(accessToken);
   credential.setExpiresInSeconds(expiresInSeconds);
   credential.setRefreshToken(refreshToken);
}

從GoogleAuthUtil ID令牌流遷移

如果您使用GoogleAuthUtil獲取ID令牌,則應遷移到新的Sign-In API ID令牌流

例如,如果您的Android代碼類似於以下示例,則應進行遷移:

Android代碼

在此示例中,ID令牌請求使用audience:server:client_id加上您的Web服務器的客戶端ID作為GoogleAuthUtil.getToken調用( audience:server:client_id:9414861317621.apps.googleusercontent.com )的“作用域”參數。

新的登錄API ID令牌流具有以下優點:

  • 一鍵式簡化登錄體驗
  • 您的服務器可以獲取用戶配置文件信息,而無需額外的網絡呼叫

要遷移到ID令牌流,請進行以下更改:

Android客戶端

  • 如果您請求,請刪除GET_ACCOUNTS (聯繫人)權限
  • Auth.GOOGLE_SIGN_IN_APIGoogleSignInOptions.Builder.requestIdToken(...) GoogleAuthUtilPlus.APIAccountPicker.newChooseAccountIntent()AccountManager.newChooseAccountIntent() Auth.GOOGLE_SIGN_IN_APIGoogleSignInOptions.Builder.requestIdToken(...)

服務器端

與使用不推薦使用的格式的GoogleAuthUtil.getToken不同,新的Sign-In API發出符合OpenID Connect規範的ID令牌。特別是,發行人現https://accounts.google.com ,以https模式。

在遷移過程中,您的服務器需要同時從新舊Android客戶端中驗證ID令牌。要驗證令牌的兩種格式,請進行與所使用的客戶端庫相對應的更改(如果使用的是一種):

  • Java(Google API客戶端庫):升級到1.21.0或更高版本
  • PHP(Google API客戶端庫):如果使用v1,請升級到1.1.6或更高版本;如果您使用v2,請升級到2.0.0-RC1或更高版本
  • Node.js:升級到0.9.7或更高版本
  • Python或您自己的實現:接受以下兩個發行者: https://accounts.google.com : https://accounts.google.comaccounts.google.com

從GoogleAuthUtil服務器身份驗證代碼流遷移

如果您使用GoogleAuthUtil獲取服務器身份驗證代碼,則應遷移到新的Sign-In API身份驗證代碼流

例如,如果您的Android代碼類似於以下示例,則應進行遷移:

Android代碼

在該示例中,服務器身份驗證代碼請求使用oauth2:server:client_id +您的Web服務器的客戶端ID作為GoogleAuthUtil.getToken調用( oauth2:server:client_id:9414861317621.apps.googleusercontent.com )的scope參數。

新的登錄API身份驗證代碼流具有以下優點:

  • 一鍵式簡化登錄體驗
  • 如果您遵循以下遷移指南,則在執行身份驗證代碼交換時,您的服務器可以獲得包含用戶個人資料信息的ID令牌

要遷移到新的身份驗證代碼流,請進行以下更改:

Android客戶端

  • 如果您請求,請刪除GET_ACCOUNTS (聯繫人)權限
  • 使用GoogleSignInOptions.Builder.requestServerAuthCode(...)配置將使用GoogleAuthUtilPlus.APIAccountPicker.newChooseAccountIntent()AccountManager.newChooseAccountIntent()任何代碼切換到Auth.GOOGLE_SIGN_IN_API

服務器端

保留當前代碼,但在構造GoogleAuthorizationCodeTokenRequest對象時將https://oauth2.googleapis.com/token指定為令牌服務器端點,以便您可以獲取包含用戶電子郵件,用戶ID和個人資料信息的ID令牌,而無需需要另一個網絡呼叫。該端點是完全向後兼容的,以下代碼適用於從您的新舊Android客戶端實現中檢索到的服務器身份驗證代碼。

GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(
                transport,
                jsonFactory,
                // Use below for tokenServerEncodedUrl parameter
                "https://oauth2.googleapis.com/token",
                clientSecrets.getDetails().getClientId(),
                clientSecrets.getDetails().getClientSecret(),
                authCode,
                REDIRECT_URI)
               .execute();

...

// You can also get an ID token from auth code exchange.
GoogleIdToken googleIdToken = tokenResponse.parseIdToken();
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
        .setAudience(Arrays.asList(SERVER_CLIENT_ID))
        .setIssuer("https://accounts.google.com")
        .build();
// Refer to ID token documentation to see how to get data from idToken object.
GoogleIdToken idToken = verifier.verify(idTokenString);
...