- この記事は、Google Sign-In for Android に関する記事を和訳したものです。
- 原文: Migrate from GoogleAuthUtil and Plus.API
- 元記事のライセンスは CC-BYで、この和訳記事のライセンスは CC-BYです。
- 自己責任でご利用ください。
- 和訳した時期は 2019年6月ころです。
もし、GoogleAuthUtil.getToken
あるいは Plus.API
を使用して過去に Googleサインインと統合したならば、より良いセキュリティおよびより良いユーザエクスペリエンスのために、最新のサインイン APIにマイグレーションする必要があります。
アクセストーンのアンチパターンからマイグレーションする
GoogleAuthUtil.getToken
を用いて取得したアクセストーンを、IDアサーションとしてあなたのバックエンドサーバに送信すべきではありません、トークンがあなたのバックエンドに発行されたことを簡単に検証することはできないので、攻撃者からのアクセストーンの挿入に対して脆弱なままとなります。
例えば、あなたの Androidコードが以下の例のようになっているならば、あなたのアプリを現在のベストプラクティスにマイグレーションする必要があります。
この例では、アクセストーンは、GoogleAuthUtil.getToken
呼び出しのための scope
パラメータとして、oauth2:
と、スコープ文字列を使用します(oauth2:https://www.googleapis.com/auth/plus.login
)。
GoogleAuthUtil.getToken
を用いて受け取るアクセストークンを用いて認証する代わりに、IDトークンフローあるいは認証コードフローのいずれかを使用してください。
IDトークンフローにマイグレーションする
もし、ユーザの ID、電子メールアドレス、名前、あるいはプロファイル写真の URLが必要とするすべてであるならば、IDトークンフローを使用します。
IDトークンフローにマイグレーションするには、以下の変更を行います:
Androidクライアント側
-
もしそれをリクエストしているならば、
GET_ACCOUNTS
(Contacts)パーミッションを削除します -
GoogleAuthUtil
、Plus.API
、AccountPicker.newChooseAccountIntent()
、あるいはAccountManager.newChooseAccountIntent()
を使用しているコードを、GoogleSignInOptions.Builder.requestIdToken(...)
構成を用いたAuth.GOOGLE_SIGN_IN_API
に切り替えます。
サーバ側
- IDトークン認証のための新しいエンドポイントを作成します
- あなたのクライアントアプリがマイグレーションされた後、古いエンドポイントをオフにします
サーバ認証コードフローにマイグレーションする
もし、あなたのサーバが、Google Drive、Youtube、あるいは、Contactsといった、他の Google APIにアクセスすることを必要とするならば、サーバ認証コードフローを使用します。
サーバ認証コードフローにマイグレーションするには、以下の変更を行います:
Androidクライアント側
-
もしそれをリクエストしているならば、
GET_ACCOUNTS
(Contacts)パーミッションを削除します -
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トークンフローからマイグレーションする
もし、IDトークンを取得するために GoogleAuthUtil
を使用しているならば、新しいサインイン APIのIDトークンフローにマイグレーションする必要があります。
例えば、もしあなたの Androidコードが次の例のようになっているならば、マイグレーションする必要があります:
この例では、IDトークンのリクエストは、GoogleAuthUtil.getToken
呼び出しのための ‘scope’ パラメータとして、audience:server:client_id
と、あなたのウェブサーバのためのクライアント IDを使用します(audience:server:client_id:9414861317621.apps.googleusercontent.com
)。
新しいサインイン APIの IDトークンフローは、次の利点を持っています:
- 合理化された、ワンタップのサインインエクスペリエンス
- あなたのサーバは、追加のネットワーク呼び出しなしでユーザのプロファイル情報を取得することができる
IDトークンフローにマイグレーションするには、以下の変更を行います:
Androidクライアント側
-
もしそれをリクエストしているならば、
GET_ACCOUNTS
(Contacts)パーミッションを削除します -
GoogleAuthUtil
、code>Plus.API、AccountPicker.newChooseAccountIntent()
、あるいはAccountManager.newChooseAccountIntent()
を使用しているコードを、GoogleSignInOptions.Builder.requestIdToken(...)
構成を用いたAuth.GOOGLE_SIGN_IN_API
に切り替えます。
サーバ側
新しいサインイン APIは、OpenID Connect仕様に準拠した IDトークンを発行します、それは、GoogleAuthUtil.getToken
とは異なります、それは、廃止予定の形式を使用しています。
特に、発行者は、今や https://accounts.google.com
になります、それは、https
スキーマを伴います。
あなたのマイグレーションプロセス中に、あなたのサーバは、あなたの古い、および、新しい Androidクライアントの両方からの IDトークンを検証する必要があります。 両方のトークンの形式を検証するには、使用するクライアントライブラリに対応する変更を行います(それを使用している場合):
- Java (Google APIs Client Libraries): 1.21.0以降にアップグレードする
- PHP (Google APIs Client Libraries): もし v1を使用しているならば、1.1.6以降にアップグレードする; もし v2を使用しているならば、2.0.0-R1以降にアップグレードする
- Node.js: 0.9.7以降にアップグレードする
-
Pythonあるいは独自の実装:
https://accounts.google.com
とaccounts.google.com
の両方の発行者を受け入れる
GoogleAuthUtilサーバ認証コードフローからマイグレーションする
もし、サーバ認証コードを取得するために GoogleAuthUtil
を使用しているならば、新しいサインイン APIの認証コードフローにマイグレーションする必要があります。
例えば、もしあなたの Androidアプリが次の例のようになっているならば、マイグレーションする必要があります:
この例では、サーバ認証コードのリクエストは、GoogleAuthUtil.getToken
呼び出しのための scope
パラメータとして、oauth2:server:client_id
と、あなたのウェブサーバのためのクライアント IDを使用します(oauth2:server:client_id:9414861317621.apps.googleusercontent.com
)。
新しいサインイン APIの ID認証コードフローは、次の利点を持っています:
- 合理化された、ワンタップのサインインエクスペリエンス
- もし以下のマイグレーションガイドに従うならば、認証コードを交換するとき、ユーザのプロファイル情報を含んでいる IDトークンを取得することができます
新しい認証コードフローにマイグレーションするには、以下の変更を行います:
Androidクライアント側
-
もしそれをリクエストしているならば、
GET_ACCOUNTS
(Contacts)パーミッションを削除します -
GoogleAuthUtil
、Plus.API
、AccountPicker.newChooseAccountIntent()
、あるいはAccountManager.newChooseAccountIntent()
を使用しているコードを、GoogleSignInOptions.Builder.requestServerAuthCode(...)
構成を伴うAuth.GOOGLE_SIGN_IN_API
に切り替えます。
サーバ側
あなたの現在のコードを維持します、ただし、GoogleAuthorizationCodeTokenRequest
オブジェクトを構築するとき、トークンサーバのエンドポイントとして https://www.googleapis.com/oauth2/v4/token
を指定します、そうすれば、別のネットワーク呼び出しを必要とせずに、ユーザの電子メール、ユーザ ID、およびプロファイル情報を取得することができます。
このエンドポイントは完全に後方互換性があり、以下のコードは、あなたの古い、および新しい Androidクライアントの実装から取得されたサーバ認証コードに対して動作するでしょう。
GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest( transport, jsonFactory, // Use below for tokenServerEncodedUrl parameter "https://www.googleapis.com/oauth2/v4/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); ...