Google から返された ID トークンは、パラメータ名 credential
で HTTP POST
メソッド リクエストによってログイン エンドポイントに送信されます。
Python 言語の例を次に示します。これは、ID トークンを検証して使用する通常の手順を示しています。
クロスサイト リクエスト フォージェリ(CSRF)トークンを検証します。ログイン エンドポイントに認証情報を送信すると、Google は double-submit-cookie パターンを使用して CSRF 攻撃を防ぎます。送信前にトークンが生成されます。その後、次のコードサンプルに示すように、トークンが Cookie と POST 本文の両方に挿入されます。
csrf_token_cookie = self.request.cookies.get('g_csrf_token') if not csrf_token_cookie: webapp2.abort(400, 'No CSRF token in Cookie.') csrf_token_body = self.request.get('g_csrf_token') if not csrf_token_body: webapp2.abort(400, 'No CSRF token in post body.') if csrf_token_cookie != csrf_token_body: webapp2.abort(400, 'Failed to verify double submit cookie.')
ID トークンを確認します。
トークンが有効であることを確認するには、次の条件を満たしていることを確認します。
- ID トークンが Google によって適切に署名されている。Google の公開鍵(JWK または PEM 形式で入手可能)を使用して、トークンの署名を検証します。これらの鍵は定期的にローテーションされます。レスポンスの
Cache-Control
ヘッダーを調べて、鍵を再度取得する必要があるタイミングを判断します。 - ID トークン内の
aud
の値が、アプリのクライアント ID のいずれかと等しい。このチェックは、悪意のあるアプリに対して発行された ID トークンが、アプリのバックエンド サーバー上の同じユーザーのデータにアクセスするために使用されることを防ぐために必要です。 - ID トークン内の
iss
の値がaccounts.google.com
またはhttps://accounts.google.com
であること。 - ID トークンの有効期限(
exp
)が過ぎていません。 - ID トークンが Google Workspace または Cloud の組織アカウントを表すことを検証する必要がある場合は、ユーザーのホスト ドメインを示す
hd
クレームを確認できます。リソースへのアクセスを特定のドメインのメンバーのみに制限する場合は、このオプションを使用する必要があります。このクレームがない場合、アカウントは Google がホストするドメインに属していません。
これらの検証手順を実行するコードを独自に記述するのではなく、お使いのプラットフォーム用の Google API クライアント ライブラリまたは汎用の JWT ライブラリを使用することを強くおすすめします。開発とデバッグの場合は、
tokeninfo
検証エンドポイントを呼び出すことができます。Google API クライアント ライブラリの使用
本番環境で Google ID トークンを検証するには、いずれかの Google API クライアント ライブラリ(Java、Node.js、PHP、Python など)を使用することをおすすめします。
Java Java で ID トークンを検証するには、 GoogleIdTokenVerifier オブジェクトを使用します。例:
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; ... GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory) // Specify the CLIENT_ID of the app that accesses the backend: .setAudience(Collections.singletonList(CLIENT_ID)) // Or, if multiple clients access the backend: //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3)) .build(); // (Receive idTokenString by HTTPS POST) GoogleIdToken idToken = verifier.verify(idTokenString); if (idToken != null) { Payload payload = idToken.getPayload(); // Print user identifier String userId = payload.getSubject(); System.out.println("User ID: " + userId); // Get profile information from payload String email = payload.getEmail(); boolean emailVerified = Boolean.valueOf(payload.getEmailVerified()); String name = (String) payload.get("name"); String pictureUrl = (String) payload.get("picture"); String locale = (String) payload.get("locale"); String familyName = (String) payload.get("family_name"); String givenName = (String) payload.get("given_name"); // Use or store profile information // ... } else { System.out.println("Invalid ID token."); }
GoogleIdTokenVerifier.verify()
メソッドは、JWT 署名、aud
クレーム、iss
クレーム、exp
クレームを検証します。ID トークンが Google Workspace または Cloud の組織アカウントを表すことを検証する必要がある場合は、
Payload.getHostedDomain()
メソッドから返されたドメイン名を確認してhd
クレームを検証できます。アカウントをドメインまたは組織によって管理するには、email
クレームのドメインだけでは不十分です。Node.js Node.js で ID トークンを検証するには、Node.js 用の Google 認証ライブラリを使用します。ライブラリをインストールします。
npm install google-auth-library --save
次に、verifyIdToken()
関数を呼び出します。例:const {OAuth2Client} = require('google-auth-library'); const client = new OAuth2Client(); async function verify() { const ticket = await client.verifyIdToken({ idToken: token, audience: CLIENT_ID, // Specify the CLIENT_ID of the app that accesses the backend // Or, if multiple clients access the backend: //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3] }); const payload = ticket.getPayload(); const userid = payload['sub']; // If the request specified a Google Workspace domain: // const domain = payload['hd']; } verify().catch(console.error);
verifyIdToken
関数は、JWT 署名、aud
クレーム、exp
クレーム、iss
クレームを検証します。ID トークンが Google Workspace または Cloud の組織アカウントを表すことを検証する必要がある場合は、ユーザーのホスト ドメインを示す
hd
クレームを確認できます。リソースへのアクセスを特定のドメインのメンバーのみに制限する場合は、このオプションを使用する必要があります。このクレームがない場合、アカウントは Google がホストするドメインに属していません。PHP PHP で ID トークンを検証するには、PHP 用 Google API クライアント ライブラリを使用します。 Composer を使用するなどしてライブラリをインストールします。
composer require google/apiclient
次に、verifyIdToken()
関数を呼び出します。例:require_once 'vendor/autoload.php'; // Get $id_token via HTTPS POST. $client = new Google_Client(['client_id' => $CLIENT_ID]); // Specify the CLIENT_ID of the app that accesses the backend $payload = $client->verifyIdToken($id_token); if ($payload) { $userid = $payload['sub']; // If the request specified a Google Workspace domain //$domain = $payload['hd']; } else { // Invalid ID token }
verifyIdToken
関数は、JWT 署名、aud
クレーム、exp
クレーム、iss
クレームを検証します。ID トークンが Google Workspace または Cloud の組織アカウントを表すことを検証する必要がある場合は、ユーザーのホスト ドメインを示す
hd
クレームを確認できます。リソースへのアクセスを特定のドメインのメンバーのみに制限する場合は、このオプションを使用する必要があります。このクレームがない場合、アカウントは Google がホストするドメインに属していません。Python Python で ID トークンを検証するには、verify_oauth2_token 関数を使用します。例:
from google.oauth2 import id_token from google.auth.transport import requests # (Receive token by HTTPS POST) # ... try: # Specify the CLIENT_ID of the app that accesses the backend: idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID) # Or, if multiple clients access the backend server: # idinfo = id_token.verify_oauth2_token(token, requests.Request()) # if idinfo['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]: # raise ValueError('Could not verify audience.') # If the request specified a Google Workspace domain # if idinfo['hd'] != DOMAIN_NAME: # raise ValueError('Wrong domain name.') # ID token is valid. Get the user's Google Account ID from the decoded token. userid = idinfo['sub'] except ValueError: # Invalid token pass
verify_oauth2_token
関数は、JWT 署名、aud
クレーム、exp
クレームを検証します。また、verify_oauth2_token
が返すオブジェクトを調べて、hd
クレームを検証する必要があります(該当する場合)。複数のクライアントがバックエンド サーバーにアクセスする場合は、aud
クレームも手動で確認します。- ID トークンが Google によって適切に署名されている。Google の公開鍵(JWK または PEM 形式で入手可能)を使用して、トークンの署名を検証します。これらの鍵は定期的にローテーションされます。レスポンスの
トークンの有効性を確認したら、Google ID トークンの情報を使用して、サイトのアカウント ステータスを関連付けることができます。
未登録のユーザー: 必要に応じてユーザーが追加のプロフィール情報を提供できる登録ユーザー インターフェース(UI)を表示できます。また、ユーザーは新しいアカウントを作成し、ログインしているユーザー セッションをサイレントに作成できます。
サイトにすでに存在するアカウント: エンドユーザーがパスワードを入力し、以前のアカウントを Google 認証情報にリンクできるウェブページを表示できます。これにより、ユーザーが既存のアカウントにアクセスできることを確認します。
連携ユーザーの復帰: ユーザーはサイレント ログインできます。