Google Identity Services ライブラリを使用すると、ユーザーはブラウザベースのポップアップまたはリダイレクト UX フローを使用して Google に認証コードをリクエストできます。これにより、安全な OAuth 2.0 フローが開始され、ユーザーの代わりに Google API を呼び出すために使用されるアクセス トークンが生成されます。
OAuth 2.0 認可コードフローの概要:
- Google アカウントの所有者は、ブラウザから、ボタンのクリックなどの操作で Google に認証コードをリクエストします。
- Google が応答して、一意の認証コードを送信するか、ユーザーのブラウザで実行されている JavaScript ウェブアプリのコールバックに送信するか、ブラウザのリダイレクトを使用して認可コード エンドポイントを直接呼び出します。
- バックエンド プラットフォームが認可コード エンドポイントをホストし、コードを受信します。検証後、Google のトークン エンドポイントへのリクエストを使用して、このコードがユーザーごとのアクセス トークンと更新トークンと交換されます。
- Google は認証コードを検証し、リクエストが安全なプラットフォームから発行されたものであることを確認し、アクセス トークンと更新トークンを発行して、プラットフォームでホストされているログイン エンドポイントを呼び出してトークンを返します。
- ログイン エンドポイントはアクセス トークンと更新トークンを受け取り、後で使用するために更新トークンを安全に保存します。
コード クライアントを初期化する
google.accounts.oauth2.initCodeClient()
メソッドはコード クライアントを初期化します。
ポップアップ モードまたはリダイレクト モード
認証コードの共有には、リダイレクトモードまたはポップアップ モードのいずれかのユーザーフローを使用できます。リダイレクト モードでは、お客様のサーバーで OAuth2 認可エンドポイントをホストし、Google がユーザー エージェントをこのエンドポイントにリダイレクトして、認証コードを URL パラメータとして共有します。ポップアップ モードでは、認証コードをサーバーに送信する JavaScript コールバック ハンドラを定義します。ポップアップ モードを使用すると、訪問者がサイトを離れることなく、シームレスなユーザー エクスペリエンスを提供できます。
次の目的でクライアントを初期化するには:
UX フローをリダイレクトし、
ux_mode
をredirect
に設定し、redirect_uri
の値をプラットフォームの認可コード エンドポイントに設定します。この値は、API Console で構成した OAuth 2.0 クライアント用に承認済みのリダイレクト URI のいずれかと完全に一致している必要があります。また、Google のリダイレクト URI の検証ルールにも準拠している必要があります。UX フローをポップアップし、
ux_mode
をpopup
に設定し、callback
の値をプラットフォームに認証コードを送信するために使用する関数の名前を設定します。
CSRF 攻撃の防止
クロスサイト リクエスト フォージェリ(CSRF)攻撃を防ぐため、リダイレクト モードとポップアップ モードの UX フローでは若干異なる手法が使用されます。リダイレクト モードでは、OAuth 2.0 の state パラメータが使用されます。state パラメータの生成と検証の詳細については、RFC6749 のセクション 10.12 クロスサイト リクエスト フォージェリをご覧ください。ポップアップ モードでは、カスタム HTTP ヘッダーをリクエストに追加し、期待される値と送信元と一致していることをサーバー上で確認します。
UX モードを選択すると、認証コードと CSRF 処理を示すコード スニペットが表示されます。
リダイレクト モード
Google がユーザーのブラウザを認証エンドポイントにリダイレクトするクライアントを初期化し、URL パラメータとして認証コードを共有します。
const client = google.accounts.oauth2.initCodeClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
ux_mode: 'redirect',
redirect_uri: "https://your.domain/code_callback_endpoint",
state: "YOUR_BINDING_VALUE"
});
ポップアップ モード
ユーザーのブラウザが Google から認証コードを受け取ってサーバーに送信するクライアントを初期化します。
const client = google.accounts.oauth2.initCodeClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
ux_mode: 'popup',
callback: (response) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', code_receiver_uri, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// Set custom header for CRSF
xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');
xhr.onload = function() {
console.log('Auth code response: ' + xhr.responseText);
};
xhr.send('code=' + response.code);
},
});
OAuth 2.0 のコードフローをトリガーする
コード クライアントの requestCode()
メソッドを呼び出して、ユーザーフローをトリガーします。
<button onclick="client.requestCode();">Authorize with Google</button>
この場合、ユーザーは Google アカウントにログインして、リダイレクト エンドポイントまたはコールバック ハンドラに認可コードを返す前に、個々のスコープを共有することに同意する必要があります。
認証コードの処理
Google がユーザーごとに一意の認証コードを生成します。このコードは、お客様がバックエンド サーバーで受信して検証します。
ポップアップ モードでは、ユーザーのブラウザで実行されている callback
で指定されたハンドラが、プラットフォームでホストされているエンドポイントに認可コードをリレーします。
リダイレクト モードの場合、GET
リクエストは redirect_url
で指定されたエンドポイントに送信され、URL code パラメータの認可コードを共有します。認証コードを受け取るには:
既存の実装がない場合は、新しい認可エンドポイントを作成します。
GET
リクエストと URL パラメータを受け入れるように、既存のエンドポイントを更新します。以前は、ペイロードに認証コード値が含まれるPUT
リクエストが使用されていました。
承認エンドポイント
認可コード エンドポイントは、次の URL クエリ文字列パラメータを含む GET
リクエストを処理する必要があります。
名前 | 値 |
---|---|
authuser | ユーザー ログイン認証のリクエスト |
コード | Google によって生成された OAuth2 認証コード |
HD | ユーザー アカウントのホスト ドメイン |
プロンプト | ユーザーの同意ダイアログ |
スコープ | 承認する 1 つ以上の OAuth2 スコープのスペース区切りリスト |
state | CRSF 状態変数 |
example.com でホストされている auth-code という名前のエンドポイントへの URL パラメータを含む GET
リクエストの例:
Request URL: https://www.example.com/auth-code?state=42a7bd822fe32cc56&code=4/0AX4XfWiAvnXLqxlckFUVao8j0zvZUJ06AMgr-n0vSPotHWcn9p-zHCjqwr47KHS_vDvu8w&scope=email%20profile%20https://www.googleapis.com/auth/calendar.readonly%20https://www.googleapis.com/auth/photoslibrary.readonly%20https://www.googleapis.com/auth/contacts.readonly%20openid%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile&authuser=0&hd=example.com&prompt=consent
以前の JavaScript ライブラリによって、または Google OAuth 2.0 エンドポイントの直接呼び出しによって認可コードフローが開始されると、POST
リクエストが使用されます。
POST
リクエストの例(HTTP リクエスト本文に認証コードをペイロードとして含む):
Request URL: https://www.example.com/auth-code
Request Payload: 4/0AX4XfWhll-BMV82wi4YwbrSaTPaRpUGpKqJ4zBxQldU\_70cnIdh-GJOBZlyHU3MNcz4qaw
リクエストを検証します
サーバーで CSRF 攻撃を回避するには、次のようにします。
リダイレクト モードの state パラメータの値を確認します。
X-Requested-With: XmlHttpRequest
ヘッダーがポップアップ モードに設定されていることを確認します。
認可コード リクエストの検証が完了している場合にのみ、Google から更新トークンとアクセス トークンを取得してください。
アクセス トークンと更新トークンを取得する
バックエンド プラットフォームが Google から認証コードを受け取ってリクエストを確認したら、その認証コードを使用して Google からアクセス トークンを取得し、API 呼び出し用のトークンを更新します。
ウェブサーバー アプリケーションでの OAuth 2.0 の使用ガイドのステップ 5: 更新トークンとアクセス トークンの認可コードを交換するからこちらの手順を行います。
トークンの管理
プラットフォームが更新トークンを安全に保管している。ユーザー アカウントが削除された場合、または google.accounts.oauth2.revoke
によって、または https://myaccount.google.com/permissions から直接ユーザーの同意が取り消された場合、保存されている更新トークンを削除します。
必要に応じて、RISC を使用して、クロスアカウント保護でユーザー アカウントを保護することもできます。
バックエンド プラットフォームは通常、アクセス トークンを使用して Google API を呼び出します。ウェブアプリがユーザーのブラウザからも Google API を直接呼び出す場合は、アクセス トークンをウェブ アプリケーションと共有する方法を実装する必要があります。そのようにする方法は、このガイドの対象外です。この方法で JavaScript 用の Google API クライアント ライブラリを使用する場合は、gapi.client.SetToken()
を使用してアクセス トークンを一時的にブラウザメモリに保存し、ライブラリで Google API を呼び出せるようにします。