如果您先前使用 GoogleAuthUtil.getToken
或 Plus.API
整合 Google 登入,建議您改用最新的登入 API,以提升安全性並享有更優質的使用者體驗。
從存取權杖反模式遷移
您不得使用 GoogleAuthUtil.getToken
取得的存取權杖做為識別宣告使用的後端伺服器,因為您無法輕易確認權杖是否已傳送至後端,導致容易插入攻擊者的存取權杖。
舉例來說,如果您的 Android 程式碼與以下範例相似,則應將應用程式遷移至目前的最佳做法。
在此範例中,存取權杖要求使用 oauth2:
加上範圍字串,做為 GoogleAuthUtil.getToken
呼叫 (oauth2:https://www.googleapis.com/auth/plus.login
) 的 scope
參數。
請使用 ID 權杖流程或驗證碼流程,而不是使用透過 GoogleAuthUtil.getToken
取得的存取權杖進行驗證。
遷移至 ID 權杖流程
如果您只需要使用者的 ID、電子郵件地址、名稱或個人資料相片網址,請使用 ID 權杖流程。
如要遷移至 ID 權杖流程,請進行下列變更:
Android 用戶端
- 要求移除
GET_ACCOUNTS
(聯絡人) 權限 - 使用
GoogleAuthUtil
設定,使用GoogleAuthUtil
、Plus.API
、AccountPicker.newChooseAccountIntent()
或AccountManager.newChooseAccountIntent()
切換任何程式碼至Auth.GOOGLE_SIGN_IN_API
。
伺服器端
- 為 ID 權杖驗證建立新的端點
- 遷移用戶端應用程式後,停用舊端點
遷移至伺服器驗證碼流程
如果您的伺服器需要存取其他 Google API (例如 Google 雲端硬碟、YouTube 或聯絡人),請使用伺服器驗證碼流程。
如要遷移至伺服器驗證碼流程,請進行下列變更:
Android 用戶端
- 要求移除
GET_ACCOUNTS
(聯絡人) 權限 - 使用
GoogleAuthUtil
設定,使用GoogleAuthUtil
、Plus.API
、AccountPicker.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 程式碼如以下範例所示,則應進行遷移:
在範例中,ID 權杖要求使用 audience:server:client_id
加上網路伺服器的用戶端 ID 做為 GoogleAuthUtil.getToken
呼叫 (audience:server:client_id:9414861317621.apps.googleusercontent.com
) 的「範圍」參數。
新版登入 API ID 權杖流程具備下列優點:
- 簡化的一鍵登入體驗
- 您的伺服器不必額外網路呼叫,就能取得使用者個人資料
如要遷移至 ID 權杖流程,請進行下列變更:
Android 用戶端
- 要求移除
GET_ACCOUNTS
(聯絡人) 權限 - 使用
GoogleAuthUtil
設定,使用GoogleAuthUtil
、Plus.API
、AccountPicker.newChooseAccountIntent()
或AccountManager.newChooseAccountIntent()
切換任何程式碼至Auth.GOOGLE_SIGN_IN_API
。
伺服器端
新的 登入 API 會核發符合 OpenID Connect 規格的 ID 權杖,這點與使用已淘汰格式的 GoogleAuthUtil.getToken
不同。具體來說,核發者現在是 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
和accounts.google.com
從 GoogleAuthUtil 伺服器驗證碼流程遷移
如果您使用 GoogleAuthUtil
取得伺服器驗證碼,則應遷移至新的 Sign-In API 驗證碼流程。
舉例來說,如果您的 Android 程式碼如以下範例所示,則應進行遷移:
在範例中,伺服器驗證碼要求使用 oauth2:server:client_id
+ 網路伺服器的用戶端 ID 做為 GoogleAuthUtil.getToken
呼叫 (oauth2:server:client_id:9414861317621.apps.googleusercontent.com
) 的 scope
參數。
新版登入 API 驗證碼流程具備下列優點:
- 簡化的一鍵登入體驗
- 按照下方的遷移指南操作,當您執行驗證碼交換作業時,您的伺服器可能會取得包含使用者個人資訊的 ID 權杖
如要遷移至新的驗證碼流程,請進行下列變更:
Android 用戶端
- 要求移除
GET_ACCOUNTS
(聯絡人) 權限 - 使用
GoogleAuthUtil
設定,使用GoogleAuthUtil
、Plus.API
、AccountPicker.newChooseAccountIntent()
或AccountManager.newChooseAccountIntent()
切換任何程式碼至Auth.GOOGLE_SIGN_IN_API
。
伺服器端
保留目前的程式碼,但在建構 GoogleAuthorizationCodeTokenRequest
物件時將 https://oauth2.googleapis.com/token
指定為權杖伺服器端點,這樣您就能取得使用者的電子郵件、使用者 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); ...