過去に GoogleAuthUtil.getToken
または Plus.API
を使用して Google ログインと統合したことがある場合は、セキュリティとユーザー エクスペリエンスを向上させるために、最新の Sign-In API に移行する必要があります。
アクセス トークンのアンチパターンから移行する
GoogleAuthUtil.getToken
で取得したアクセス トークンを ID アサーションとしてバックエンド サーバーに送信しないでください。トークンがバックエンドに発行されたものを簡単には確認できず、攻撃者がアクセス トークンを挿入してしまうおそれがあります。
たとえば、Android のコードが以下の例のような場合は、アプリを現在のベスト プラクティスに移行する必要があります。
この例では、アクセス トークン リクエストで oauth2:
とスコープ文字列を GoogleAuthUtil.getToken
呼び出し(oauth2:https://www.googleapis.com/auth/plus.login
)の scope
パラメータとして使用します。
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 トークンのリクエストでは、GoogleAuthUtil.getToken
呼び出し(audience:server:client_id:9414861317621.apps.googleusercontent.com
)の「scope」パラメータとして、audience:server:client_id
とウェブサーバーのクライアント ID を使用します。
新しい Sign-In API ID トークンのフローには、次の利点があります。
- 効率的なワンタップ ログイン エクスペリエンス
- サーバーは追加のネットワーク呼び出しを必要とせずにユーザーのプロフィール情報を取得できます
ID トークンのフローに移行するには、次の変更を行います。
Android クライアント側
GET_ACCOUNTS
(連絡先)の権限をリクエストする場合は削除するGoogleAuthUtil
、Plus.API
、AccountPicker.newChooseAccountIntent()
、またはAccountManager.newChooseAccountIntent()
を使用しているコードを、GoogleSignInOptions.Builder.requestIdToken(...)
構成のAuth.GOOGLE_SIGN_IN_API
に切り替えます。
サーバーサイド
新しい Sign-In API は、非推奨の形式を使用する GoogleAuthUtil.getToken
とは異なり、OpenID Connect 仕様に準拠した ID トークンを発行します。具体的には、発行者は https
スキーマの https://accounts.google.com
になりました。
移行プロセス中に、サーバーは新旧両方の 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 コードが次の例のような場合は、移行する必要があります。
この例では、サーバー認証コードのリクエストでは、GoogleAuthUtil.getToken
呼び出し(oauth2:server:client_id:9414861317621.apps.googleusercontent.com
)の scope
パラメータとして、oauth2:server:client_id
とウェブサーバーのクライアント ID を使用します。
新しい 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 クライアント実装から取得したサーバー認証コードで機能します。
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); ...