OAuth と Google でログインによるリンクの簡素化

概要

OAuth ベースの Google でログインの簡素化されたリンクは、OAuth リンクの上層に Google でログインを追加します。これにより、Google ユーザーにシームレスなリンク エクスペリエンスを提供し、アカウントの作成も可能になります。ユーザーは Google アカウントを使用してサービスに新しいアカウントを作成できます。

OAuth と Google でログインを使用してアカウント リンクを行うには、次の一般的な手順に従います。

  1. まず、ユーザーの Google プロフィールにアクセスすることについてユーザーに同意を求めます。
  2. プロフィールの情報を使用して、ユーザー アカウントが存在するかどうかを確認します。
  3. 既存のユーザーの場合は、アカウントをリンクします。
  4. 認証システムで Google ユーザーに一致するユーザーが見つからない場合は、Google から受け取った ID トークンを検証します。その後、ID トークンに含まれているプロフィール情報に基づいてユーザー アカウントを作成できます。
この図は、ユーザーが簡素化されたリンクフローを使用して Google アカウントをリンクする手順を示しています。最初のスクリーンショットは、ユーザーがリンクするアプリをどのように選択できるかを示します。2 つ目のスクリーンショットでは、ユーザーがサービスに既存のアカウントがあるかどうかを確認できます。3 番目のスクリーンショットでは、リンクする Google アカウントを選択できます。4 番目のスクリーンショットは、ユーザーの Google アカウントをアプリにリンクするための確認画面を示します。5 番目のスクリーンショットは、Google アプリでユーザー アカウントが正常にリンクされたことを示します。
簡素化されたリンクを使用したユーザーのスマートフォンでのアカウント リンク

図 1. ユーザーのスマートフォンでの簡素化されたリンクによるアカウント リンク

簡素化されたリンク: OAuth + 「Google でログイン」フロー

次のシーケンス図は、Streamlined Linking におけるユーザー、Google、トークン交換エンドポイント間のインタラクションの詳細を示しています。

ユーザー Google アプリ / サーバー トークン 交換エンドポイント API 1. ユーザーがリンクを開始する 2. 「Google でログイン」をリクエストする 3. Google でログイン 4. インテントを確認(JWT アサーション) 5. account_found: true/false アカウントが見つかった場合: 6. インテントを取得 アカウントが見つからなかった場合: 6. インテントを作成 7. access_token、refresh_token 8. ユーザー トークンを保存する 9. ユーザー リソースにアクセスする
図 2. Streamlined Linking フローのイベントのシーケンス。

役割と責任

次の表に、Streamlined Linking フローにおけるアクターの役割と責任を定義します。

アクター / コンポーネント GAL ロール 責任
Google アプリ / サーバー OAuth クライアント Google でログインのユーザーの同意を取得し、ID アサーション(JWT)をサーバーに渡し、結果のトークンを安全に保存します。
トークン交換エンドポイント ID プロバイダ / 認可サーバー ID アサーションを検証し、既存のアカウントを確認し、アカウント リンク インテント(checkgetcreate)を処理し、リクエストされたインテントに基づいてトークンを発行します。
サービス API リソース サーバー 有効なアクセス トークンが提示された場合にユーザーデータへのアクセスを提供します。

簡素化されたリンクの要件

  • 基本的な OAuth リンクフローを実装します。サービスは、OAuth 2.0 準拠の認証エンドポイントとトークン交換エンドポイントをサポートする必要があります。
  • トークン交換エンドポイントは、JSON Web Token(JWT)アサーションをサポートし、checkcreateget インテントを実装する必要があります。

簡素化されたリンクの決定ロジック

次のロジックは、簡略化されたリンクフローでインテントが呼び出される方法を決定します。

  1. ユーザーが認証システムにアカウントを持っているかどうか。(ユーザーが [はい] または [いいえ] を選択して決定します)
    1. はい : ユーザーは Google アカウントに関連付けられているメールアドレスを使用してプラットフォームにログインしますか?(ユーザーが [はい] または [いいえ] を選択して決定します)
      1. YES : 認証システムに一致するアカウントがユーザーにありますか?(確認のために check intent が呼び出されます)
        1. YES : get intent が呼び出され、インテントの取得が成功した場合、アカウントがリンクされます。
        2. いいえ : 新しいアカウントを作成しますか?(ユーザーが [はい] または [いいえ] を選択して決定します)
          1. YES : create intent が呼び出され、作成インテントが正常に返された場合、アカウントがリンクされます。
          2. いいえ : OAuth リンクフローがトリガーされ、ユーザーはブラウザにリダイレクトされます。ユーザーは別のメールアドレスでリンクするオプションを選択できます。
      2. いいえ : OAuth リンクフローがトリガーされ、ユーザーはブラウザにリダイレクトされ、別のメールアドレスでリンクするオプションが表示されます。
    2. NO : 認証システムに一致するアカウントがユーザーにありますか?(確認のために check intent が呼び出されます)
      1. YES : get intent が呼び出され、インテントの取得が成功した場合、アカウントがリンクされます。
      2. NO : 作成インテントが正常に返された場合、create intent が呼び出され、アカウントがリンクされます。

実装レシピ

トークン交換エンドポイントでは、Streamlined Linking をサポートするために checkgetcreate インテントを実装する必要があります。

さまざまなインテントを処理する手順は次のとおりです。

既存のユーザー アカウントを確認する(インテントを確認する)

Google はトークン交換エンドポイントを呼び出して、Google ユーザーがシステムに存在するかどうかを確認します。パラメータの詳細については、リンクインテントの簡素化をご覧ください。

実装レシピ

check インテントを処理するには、次の操作を行います。

  1. リクエストを検証する:

    • client_idclient_secretgrant_type を確認します(urn:ietf:params:oauth:grant-type:jwt-bearer である必要があります)。
    • JWT 検証の条件を使用して assertion(JWT)を検証します。
  2. ユーザーを検索:

    • JWT の Google アカウント ID(sub)またはメールアドレスが、データベース内のユーザーと一致するかどうかを確認します。
  3. 対応:

    • 見つかった場合: {"account_found": "true"} を含む HTTP 200 OK を返します。
    • 見つからない場合: {"account_found": "false"} で HTTP 404 Not Found を返します。

自動リンクを処理する(インテントを取得する)

アカウントが存在する場合、Google は intent=get を使用してエンドポイントを呼び出し、トークンを取得します。パラメータの詳細については、リンクインテントの簡素化をご覧ください。

実装レシピ

get インテントを処理するには、次の操作を行います。

  1. リクエストを検証する:

    • client_idclient_secretgrant_type を確認します。
    • assertion(JWT)を検証します。
  2. ユーザーを検索:

    • sub または email クレームを使用して、ユーザーが存在することを確認します。
  3. 対応:

    • 成功した場合: JSON レスポンス(HTTP 200 OK)で access_tokenrefresh_tokenexpires_in を生成して返します。
    • リンクに失敗した場合: HTTP 401 Unauthorized{"error": "linking_error"} を返し、必要に応じて login_hint を返して標準の OAuth リンクにフォールバックします。

Google でログインを使用したアカウントの作成(インテントの作成)を処理する

アカウントが存在しない場合、Google は intent=create を使用してエンドポイントを呼び出し、新しいユーザーを作成します。パラメータの詳細については、リンクインテントの簡素化をご覧ください。

実装レシピ

create インテントを処理するには、次の操作を行います。

  1. リクエストを検証する:

    • client_idclient_secretgrant_type を確認します。
    • assertion(JWT)を検証します。
  2. ユーザーが存在しないことを確認する:

    • sub または email がデータベースにすでに存在するかどうかを確認します。
    • ユーザーが存在する場合: HTTP 401 Unauthorized{"error": "linking_error", "login_hint": "USER_EMAIL"} を返して、OAuth リンクへのフォールバックを強制します。
  3. アカウントを作成:

    • JWT の subemailnamepicture の各クレームを使用して、新規ユーザー レコードを作成します。
  4. 対応:

    • JSON レスポンスでトークンを生成して返します(HTTP 200 OK)。

Google API クライアント ID を取得する

アカウント リンクの登録プロセスで、Google API クライアント ID を指定する必要があります。OAuth リンクの手順を完了する際に作成したプロジェクトを使用して API クライアント ID を取得します。手順は次のとおりです。

  1. [クライアント] ページに移動します。
  2. Google APIs プロジェクトを作成または選択します。

    プロジェクトにウェブ アプリケーション タイプのクライアント ID がない場合は、[クライアントを作成] をクリックして作成します。[承認済みの JavaScript 生成元] ボックスに、サイトのドメインを必ず含めてください。ローカルテストや開発を行う場合は、[承認済みの JavaScript の生成元] フィールドに http://localhosthttp://localhost:<port_number> の両方を追加する必要があります。

実装を検証する

You can validate your implementation by using the OAuth 2.0 Playground tool.

In the tool, do the following steps:

  1. Click Configuration to open the OAuth 2.0 Configuration window.
  2. In the OAuth flow field, select Client-side.
  3. In the OAuth Endpoints field, select Custom.
  4. Specify your OAuth 2.0 endpoint and the client ID you assigned to Google in the corresponding fields.
  5. In the Step 1 section, don't select any Google scopes. Instead, leave this field blank or type a scope valid for your server (or an arbitrary string if you don't use OAuth scopes). When you're done, click Authorize APIs.
  6. In the Step 2 and Step 3 sections, go through the OAuth 2.0 flow and verify that each step works as intended.

You can validate your implementation by using the Google Account Linking Demo tool.

In the tool, do the following steps:

  1. Click the Sign in with Google button.
  2. Choose the account you'd like to link.
  3. Enter the service ID.
  4. Optionally enter one or more scopes that you will request access for.
  5. Click Start Demo.
  6. When prompted, confirm that you may consent and deny the linking request.
  7. Confirm that you are redirected to your platform.