OAuth による Google アカウントのリンク

アカウントは、業界標準の OAuth 2.0 認可コードフローを使用してリンクされます。

エージェント向けの OAuth 2.1 と PKCE

ステートレス AI エージェントとマルチモーダル パイプラインには、OAuth 2.1 の適用をおすすめします。

  • PKCE(Proof Key for Code Exchange): 認可コードフローを保護し、傍受攻撃を防ぐために使用する必要があります。
  • 暗黙的フローなし: 暗黙的フローでは、アクセス トークンが URL で公開されるため、エージェント環境でセキュリティ リスクが生じます。

サービスは、OAuth 2.0/2.1 準拠の認証エンドポイントとトークン交換エンドポイントをサポートする必要があります。

プロジェクトを作成する

アカウント リンクを使用するプロジェクトを作成するには:

  1. Google API コンソールに移動します。
  2. [プロジェクトの作成] をクリックします。
  3. 名前を入力するか、生成された候補を受け入れます。
  4. 残りのフィールドを確認または編集します。
  5. [作成] をクリックします。

プロジェクト ID を表示するには:

  1. Google API コンソールに移動します。
  2. ランディング ページの表でプロジェクトを探します。プロジェクト ID は [ID] 列に表示されます。

Google アカウントのリンク プロセスには同意画面が含まれています。この画面では、データへのアクセスをリクエストしているアプリケーション、リクエストしているデータの種類、適用される規約がユーザーに通知されます。Google API クライアント ID を生成する前に、OAuth 同意画面を構成する必要があります。

  1. Google API コンソールの OAuth 同意画面 ページを開きます。
  2. プロンプトが表示されたら、作成したプロジェクトを選択します。
  3. [OAuth 同意画面] ページでフォームに入力し、[保存] ボタンをクリックします。

    アプリケーション名: 同意を求めるアプリケーションの名前。名前はアプリケーションを正確に反映し、ユーザーが他の場所で見るアプリケーション名と一致している必要があります。アプリケーション名は、アカウント リンクの同意画面に表示されます。

    アプリケーション ロゴ: 同意画面に表示される画像で、ユーザーがアプリを認識しやすくなります。ロゴは、アカウント リンクの同意画面とアカウント設定に表示されます。

    サポートメール: 同意に関して問い合わせる際に使用します。

    Google API のスコープ: スコープを使用すると、アプリケーションはユーザーの非公開の Google データにアクセスできます。Google アカウントのリンクのユースケースでは、デフォルトのスコープ(email、profile、openid)で十分です。機密性の高いスコープを追加する必要はありません。一般的に、スコープは事前にリクエストするのではなく、アクセスが必要になったときに段階的にリクエストすることが効果的な手法です。詳細

    承認済みドメイン: デベロッパーとユーザーを保護するために、Google では、OAuth を使用して認証するアプリケーションのみに承認済みドメインの使用を許可しています。アプリケーションのリンクは、承認済みドメインでホストする必要があります。詳細

    アプリケーションのホームページへのリンク: アプリケーションのホームページ。承認済みドメインでホストする必要があります。

    アプリケーションのプライバシー ポリシーへのリンク: Google アカウント リンクの同意画面に表示されます。承認済みドメインでホストする必要があります。

    アプリケーションの利用規約へのリンク(省略可): 承認済みドメインでホストする必要があります。

    図 1. 架空のアプリケーション Tunery の Google アカウントのリンクの同意画面

  4. [検証ステータス] を確認します。アプリケーションの検証が必要な場合は、[検証のために送信] ボタンを**クリック**して、検証を受けるためにアプリケーションを送信します。詳しくは、OAuth の検証要件をご覧ください。

OAuth サーバーを実装する

認可コードフローの OAuth 2.0 サーバーは 2 つのエンドポイントで構成されます。これらのエンドポイントには HTTPS 経由でアクセスできます。 最初のエンドポイントは、データアクセスに対するユーザーの同意を検索または取得する役割を担う認証エンドポイントです。認可エンドポイントは、ログインしていないユーザーにログイン用の UI を表示し、リクエストされたアクセスへの同意を記録します。2 つ目のエンドポイントはトークン交換エンドポイントで、トークンという暗号化された文字列を取得し、ユーザーにサービスへのアクセスを許可します。

Google アプリケーションでサービスの API を呼び出す必要がある場合、Google はこれらのエンドポイントを使用して、API の呼び出し許可をユーザーから取得します。

Google アカウントのリンク: OAuth 認可コードフロー

次のシーケンス図は、ユーザー、Google、サービスの各エンドポイント間のインタラクションの詳細を示しています。

ユーザー Google アプリ / ブラウザ Google サーバー 認可 エンドポイント トークン エンドポイント 1. ユーザーがリンクを開始 2. 認可エンドポイントにリダイレクト(GET) client_id、redirect_uri、state、scope 3. ログイン画面と同意画面を表示 4. ユーザーが認証して同意を付与 5. Google にリダイレクト(GET) code, state 6. リダイレクトを処理してコード/状態を渡す 7. トークン交換(POST) grant_type=authorization_code、code 8. トークンを返す(200 OK) access_token、refresh_token 9. ユーザー トークンを保存 10. ユーザーリソースにアクセス
図 1.Google アカウントのリンクの OAuth 2.0 認可コードフローのイベント シーケンス。

役割と責任

次の表に、Google アカウントのリンク(GAL)OAuth フローのアクターの役割と責任を示します。GAL では、Google が OAuth クライアントとして機能し、サービスが ID/サービス プロバイダとして機能します。

アクター / コンポーネント GAL ロール 責任
Google アプリ / サーバー OAuth クライアント フローを開始し、認証コードを受け取ってトークンと交換し、安全に保存してサービスの API にアクセスします。
認可エンドポイント 認可サーバー ユーザーを認証し、データへのアクセスを Google と共有することへの同意を得ます。
トークン交換エンドポイント 認可サーバー 認可コードと更新トークンを検証し、Google サーバーにアクセス トークンを発行します。
Google リダイレクト URI コールバック エンドポイント 認可サービスからユーザー リダイレクトを受け取り、 code 値と state 値を取得します。

Google が開始する OAuth 2.0 認可コードフローのセッションは次のような流れになります。

  1. Google がユーザーのブラウザで認可エンドポイントを開きます。アクションのフローが音声専用デバイスで開始した場合、Google は実行をスマートフォンに転送します。
  2. ユーザーがログインし(ログインしていない場合)、Google が API を使用してデータにアクセスすることを承諾します(まだ許可していない場合)。
  3. サービスが認証コードを作成し、その認証コードを Google に返します。
  4. Google が認可コードをトークン交換エンドポイントに送信します。このエンドポイントでコードの真正性が検証され、アクセス トークン更新トークンが返されます。アクセス トークンは短期のトークンで、API にアクセスするための認証情報として使用されます。更新トークンは長期のトークンで、Google が保存してアクセス トークンが期限切れになったときに新しいトークンを取得するために使用できます。
  5. ユーザーがアカウント リンクフローを完了すると、それ以降 Google から送信されるすべてのリクエストにアクセス トークンが含まれます。

実装レシピ

認可コードフローを実装する手順は次のとおりです。

ステップ 1: 認可リクエストを処理する

Google がアカウント リンクを開始すると、ユーザーは認可エンドポイントにリダイレクトされます。プロトコルの詳細な契約とパラメータ要件については、認可エンドポイントをご覧ください。

リクエストを処理する手順は次のとおりです。

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

    • client_id が Google に割り当てたクライアント ID と一致することを確認します。
    • redirect_uri が想定される Google リダイレクト URL: none https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID https://oauth-redirect-sandbox.googleusercontent.com/r/YOUR_PROJECT_ID と一致することを確認します。
    • response_typecode であることを確認します。
  2. ユーザーを認証する:

    • ユーザーがサービスにログインしているかどうか確認します。
    • ユーザーがログインしていない場合は、ログインまたは登録フローを完了するように促します。
  3. 認証コードを生成する:

    • ユーザーとクライアントに関連付けられた、推測できない一意の認証コードを作成します。
    • コードの有効期限を約 10 分に設定します。
  4. Google にリダイレクトする:

    • ブラウザを redirect_uri で指定された URL にリダイレクトします。
    • 次のクエリ パラメータを追加します。
      • code: 生成した認証コード。
      • state: Google から受け取った変更されていない状態値。

ステップ 2: トークン交換リクエストを処理する

トークン交換エンドポイントは、コードとトークンの交換と、期限切れのアクセス トークンの更新という、2 種類のリクエストを処理します。プロトコルの詳細な契約とパラメータ要件については、トークン交換エンドポイントをご覧ください。

A. 認可コードをトークンと交換する

Google が認証コードを受け取ると、トークン交換エンドポイント(POST)を呼び出してトークンを取得します。

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

    • client_idclient_secret を確認します。
    • 認証コードが有効で、期限切れになっていないことを確認します。
    • redirect_uri がステップ 1 で使用した値と一致することを確認します。
    • 検証に失敗した場合は、{"error": "invalid_grant"} を含む HTTP 400 Bad Request を返します。
  2. トークンを発行する:

    • 有効期間の長い refresh_token と有効期間の短い access_token(通常は 1 時間)を生成します。
    • 標準の JSON トークン レスポンスを含む HTTP 200 OK を返します。

B. アクセス トークンを更新する

アクセス トークンの有効期限が切れると、Google は更新トークンを使用して新しいトークンをリクエストします。

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

    • client_idclient_secretrefresh_token を確認します。
    • 検証に失敗した場合は、{"error": "invalid_grant"} を含む HTTP 400 Bad Request を返します。
  2. 新しいアクセス トークンを発行する:

    • 有効期間の短い新しい access_token を生成します。
    • JSON トークン レスポンス(必要に応じて新しい更新トークンを含む)を含む HTTP 200 OK を返します。
Handle userinfo requests

The userinfo endpoint is an OAuth 2.0 protected resource that return claims about the linked user. Implementing and hosting the userinfo endpoint is optional, except for the following use cases:

After the access token has been successfully retrieved from your token endpoint, Google sends a request to your userinfo endpoint to retrieve basic profile information about the linked user.

userinfo endpoint request headers
Authorization header The access token of type Bearer.

For example, if your userinfo endpoint is available at https://myservice.example.com/userinfo, a request might look like the following:

GET /userinfo HTTP/1.1
Host: myservice.example.com
Authorization: Bearer ACCESS_TOKEN

For your userinfo endpoint to handle requests, do the following steps:

  1. Extract access token from the Authorization header and return information for the user associated with the access token.
  2. If the access token is invalid, return an HTTP 401 Unauthorized error with using the WWW-Authenticate Response Header. Below is an example of a userinfo error response:
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: error="invalid_token",
    error_description="The Access Token expired"
    
    If a 401 Unauthorized, or any other unsuccessful error response is returned during the linking process, the error will be non-recoverable, the retrieved token will be discarded and the user will have to initiate the linking process again.
  3. If the access token is valid, return and HTTP 200 response with the following JSON object in the body of the HTTPS response:

    {
    "sub": "USER_UUID",
    "email": "EMAIL_ADDRESS",
    "given_name": "FIRST_NAME",
    "family_name": "LAST_NAME",
    "name": "FULL_NAME",
    "picture": "PROFILE_PICTURE",
    }
    If your userinfo endpoint returns an HTTP 200 success response, the retrieved token and claims are registered against the user's Google account.

    userinfo endpoint response
    sub A unique ID that identifies the user in your system.
    email Email address of the user.
    given_name Optional: First name of the user.
    family_name Optional: Last name of the user.
    name Optional: Full name of the user.
    picture Optional: Profile picture of the user.

実装の検証

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.