過去に GoogleAuthUtil.getToken
または Plus.API
を使用して Google ログインと統合していた場合は、セキュリティとユーザー エクスペリエンスを高めるため、最新の Sign-In API に移行する必要があります。
アクセス トークンのアンチパターンからの移行
GoogleAuthUtil.getToken
で取得したアクセス トークンを ID アサーションとしてバックエンド サーバーに送信しないでください。トークンがバックエンドに発行されたことは簡単には確認できず、攻撃者からアクセス トークンが挿入される危険性があります。
たとえば、Android コードが以下の例のようになっている場合は、アプリを現在のベスト プラクティスに移行する必要があります。
この例では、アクセス トークン リクエストで GoogleAuthUtil.getToken
呼び出し(oauth2:https://www.googleapis.com/auth/plus.login
)の scope
パラメータとして、oauth2:
とスコープ文字列が使用されています。
GoogleAuthUtil.getToken
で取得したアクセス トークンで認証するのではなく、ID トークンのフローまたは認証コードのフローを使用します。
ID トークンフローに移行する
ユーザー ID、メールアドレス、名前、プロフィール写真の URL のみが必要な場合は、ID トークン フローを使用します。
ID トークンのフローに移行するには、次の変更を行います。
Android クライアント側
GET_ACCOUNTS
(連絡先)権限をリクエストした場合は削除しますGoogleAuthUtil
、Plus.API
、AccountPicker.newChooseAccountIntent()
、AccountManager.newChooseAccountIntent()
を使用しているコードをGoogleSignInOptions.Builder.requestIdToken(...)
構成のAuth.GOOGLE_SIGN_IN_API
に切り替えます。
サーバー側
- ID トークン認証用の新しいエンドポイントを作成する
- クライアント アプリの移行後、古いエンドポイントを無効にする
サーバー認証コードフローへの移行
サーバーが他の Google API(Google ドライブ、YouTube、コンタクトなど)にアクセスする必要がある場合は、サーバー認証コードフローを使用します。
サーバー認証コードフローに移行するには、次のように変更します。
Android クライアント側
GET_ACCOUNTS
(連絡先)権限をリクエストした場合は削除しますGoogleAuthUtil
、Plus.API
、AccountPicker.newChooseAccountIntent()
、AccountManager.newChooseAccountIntent()
を使用しているコードをGoogleSignInOptions.Builder.requestServerAuthCode(...)
構成の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
)の「スコープ」パラメータとして使用します。
新しい Sign-In API ID トークンのフローには、次の利点があります。
- 簡素化されたワンタップ ログイン エクスペリエンス
- サーバーは追加のネットワーク呼び出しなしでユーザー プロフィール情報を取得できる
ID トークンのフローに移行するには、次の変更を行います。
Android クライアント側
GET_ACCOUNTS
(連絡先)権限をリクエストした場合は削除しますGoogleAuthUtil
、Plus.API
、AccountPicker.newChooseAccountIntent()
、AccountManager.newChooseAccountIntent()
を使用しているコードをGoogleSignInOptions.Builder.requestIdToken(...)
構成のAuth.GOOGLE_SIGN_IN_API
に切り替えます。
サーバー側
サポートが終了した形式を使用する 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
と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
パラメータとして使用します。
新しい Sign-In API 認証コードフローには、次の利点があります。
- 簡素化されたワンタップ ログイン エクスペリエンス
- 以下の移行ガイドの手順に沿って進めると、サーバーは認証コード交換を行う際に、ユーザーのプロフィール情報を含む ID トークンを取得できます。
新しい認証コードフローに移行するには、次のように変更します。
Android クライアント側
GET_ACCOUNTS
(連絡先)権限をリクエストした場合は削除しますGoogleAuthUtil
、Plus.API
、AccountPicker.newChooseAccountIntent()
、AccountManager.newChooseAccountIntent()
を使用しているコードをGoogleSignInOptions.Builder.requestServerAuthCode(...)
構成のAuth.GOOGLE_SIGN_IN_API
に切り替えます。
サーバー側
現在のコードを維持したまま、GoogleAuthorizationCodeTokenRequest
オブジェクトを作成するときにトークン サーバー エンドポイントとして https://oauth2.googleapis.com/token
を指定すると、ユーザーのメール、ユーザー ID、プロファイル情報を含む ID トークンを取得できます。別のネットワーク呼び出しは必要ありません。このエンドポイントには完全な下位互換性があるため、次のコードは、古い Android クライアントの実装と新しい 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); ...