コードモデルの使用

Google Identity Services ライブラリを使用すると、ユーザーはブラウザベースのポップアップまたはリダイレクト UX フローを使用して、Google に認証コードをリクエストできます。これにより、安全な OAuth 2.0 フローが開始され、ユーザーに代わって Google API を呼び出すために使用されるアクセス トークンが生成されます。

OAuth 2.0 認可コードフローの概要:

  • ブラウザで、ボタンをクリックするなどの操作を行うと、Google アカウントのオーナーが Google に認可コードをリクエストします。
  • Google は、ユーザーのブラウザで実行されている JavaScript ウェブアプリのコールバックに一意の認可コードを送信するか、ブラウザのリダイレクトを使用して認可コード エンドポイントを直接呼び出すことで応答します。
  • バックエンド プラットフォームが認証コード エンドポイントをホストし、コードを受け取ります。検証後、このコードは Google のトークン エンドポイントへのリクエストを使用して、ユーザーごとのアクセス トークンと更新トークンと交換されます。
  • Google は、認可コードを検証し、リクエストが安全なプラットフォームから送信されたことを確認し、アクセス トークンと更新トークンを発行して、プラットフォームでホストされているログイン エンドポイントを呼び出してトークンを返します。
  • ログイン エンドポイントはアクセス トークンと更新トークンを受け取り、更新トークンを後で使用するために安全に保存します。

前提条件

設定に記載されている手順に沿って、OAuth 同意画面を構成し、クライアント ID を取得して、クライアント ライブラリを読み込みます。

コード クライアントを初期化する

google.accounts.oauth2.initCodeClient() メソッドはコード クライアントを初期化します。

リダイレクト モードまたはポップアップ モードのユーザーフローを使用して、認証コードを共有できます。リダイレクト モードでは、OAuth2 認証エンドポイントをサーバーでホストし、Google がユーザー エージェントをこのエンドポイントにリダイレクトして、認証コードを URL パラメータとして共有します。ポップアップ モードでは、JavaScript コールバック ハンドラを定義します。このハンドラは、認証コードをサーバーに送信します。ポップアップ モードを使用すると、訪問者がサイトを離れることなくシームレスなユーザー エクスペリエンスを提供できます。

次のクライアントを初期化するには:

  • リダイレクト UX フロー。ux_moderedirect に設定し、redirect_uri の値をプラットフォームの認可コード エンドポイントに設定します。この値は、Google Cloud コンソールで構成した OAuth 2.0 クライアントの承認済みリダイレクト URI のいずれかと完全に一致する必要があります。また、リダイレクト URI の検証ルールにも準拠している必要があります。

  • ポップアップ UX フロー、ux_modepopup に設定、callback の値を、プラットフォームに認証コードを送信するために使用する関数の名前に設定します。redirect_uri の値は、デフォルトで initCodeClient を呼び出すページのオリジンになります。この値は、後でフローで認証コードをアクセス トークンまたは更新トークンと交換するときに使用されます。たとえば、https://www.example.com/index.htmlinitCodeClient を呼び出し、オリジン https://www.example.comredirect_url の値であるとします。

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_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  ux_mode: 'redirect',
  redirect_uri: 'https://oauth2.example.com/code',
  state: 'YOUR_BINDING_VALUE'
});

ユーザーがポップアップ ダイアログで認証フローを開始するクライアントを初期化します。同意が得られると、コールバック関数を使用して、Google からユーザーのブラウザに認可コードが返されます。JS コールバック ハンドラからの POST リクエストは、認証コードをバックエンド サーバーのエンドポイントに配信します。このエンドポイントで認証コードが検証され、OAuth フローの残りの部分が完了します。

const client = google.accounts.oauth2.initCodeClient({
  client_id: 'YOUR_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  ux_mode: 'popup',
  callback: (response) => {
    const xhr = new XMLHttpRequest();
    xhr.open('POST', "https://oauth2.example.com/code", 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 で指定されたハンドラが、プラットフォームでホストされているエンドポイントに認可コードを中継します。

リダイレクト モードの場合、redirect_uri で指定されたエンドポイントに GET リクエストが送信され、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 リクエストが使用されます。

HTTP リクエストの本文にペイロードとして認可コードを含む POST リクエストの例:

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 を直接呼び出す場合は、アクセス トークンをウェブ アプリケーションと共有する方法を実装する必要があります。このガイドでは、その方法については説明しません。このアプローチに従って Google API Client Library for JavaScript を使用する場合は、gapi.client.SetToken() を使用してアクセス トークンをブラウザのメモリに一時的に保存し、ライブラリが Google API を呼び出せるようにします。