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 インテントを実装する必要があります。

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

检查现有用户账号(检查 intent)

Google 会调用您的令牌交换端点,以验证 Google 用户是否存在于您的系统中。如需了解参数详情,请参阅简化的关联 intent

实现方案

如需处理 check intent,请执行以下操作:

  1. 验证请求

    • 验证 client_idclient_secretgrant_type(必须为 urn:ietf:params:oauth:grant-type:jwt-bearer)。
    • 使用 JWT 验证 中的条件验证 assertion (JWT)。
  2. 查找用户

    • 检查 JWT 中的 Google 账号 ID (sub) 或电子邮件地址是否与数据库中的用户匹配。
  3. 回应

    • 如果找到:返回 HTTP 200 OK,并附带 {"account_found": "true"}
    • 如果未找到:返回 HTTP 404 Not Found,并附带 {"account_found": "false"}

处理自动关联(获取 intent)

如果该账号存在,Google 会使用 intent=get 调用您的端点以检索令牌。如需了解参数详情,请参阅简化的关联 intent

实施方案

如需处理 get intent,请执行以下操作:

  1. 验证请求

    • 验证 client_idclient_secretgrant_type
    • 验证 assertion (JWT)。
  2. 查找用户

    • 使用 subemail 声明验证用户是否存在。
  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> の両方を追加する必要があります。

実装を検証する

OAuth 2.0 Playground ツールを使用して、実装を検証できます。

このツールで、次の手順を行います。

  1. [構成] 設定をクリックして、[OAuth 2.0 構成] ウィンドウを開きます。
  2. [OAuth flow] フィールドで、[クライアントサイド] を選択します。
  3. [OAuth Endpoints] フィールドで、[Custom] を選択します。
  4. 対応するフィールドに、OAuth 2.0 エンドポイントと Google に割り当てたクライアント ID を指定します。
  5. [Step 1] セクションで、Google スコープを選択しないでください。代わりに、このフィールドを空白のままにするか、サーバーで有効なスコープを入力します(OAuth スコープを使用しない場合は任意の文字列を入力します)。完了したら、[Authorize APIs] をクリックします。
  6. [Step 2] セクションと [Step 3] セクションで、OAuth 2.0 フローを確認し、各ステップが意図したとおりに動作することを確認します。

Google アカウント リンク デモツールを使用して、実装を検証できます。

このツールで、次の手順を行います。

  1. [Google でログイン] ボタンをクリックします。
  2. リンクするアカウントを選択します。
  3. サービス ID を入力します。
  4. 必要に応じて、アクセスをリクエストするスコープを 1 つ以上入力します。
  5. [Start Demo] をクリックします。
  6. 確認のメッセージが表示されたら、リンク リクエストに同意または拒否できることを確認します。
  7. プラットフォームにリダイレクトされることを確認します。