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 準拠の認証エンドポイントとトークン交換エンドポイントをサポートする必要があります。

Create the project

To create your project to use account linking:

  1. Go to the Google API Console.
  2. Click Create project.
  3. Enter a name or accept the generated suggestion.
  4. Confirm or edit any remaining fields.
  5. Click Create.

To view your project ID:

  1. Go to the Google API Console.
  2. Find your project in the table on the landing page. The project ID appears in the ID column.

The Google Account Linking process includes a consent screen which tells users the application requesting access to their data, what kind of data they are asking for and the terms that apply. You will need to configure your OAuth consent screen before generating a Google API client ID.

  1. Open the OAuth consent screen page of the Google APIs console.
  2. If prompted, select the project you just created.
  3. On the "OAuth consent screen" page, fill out the form and click the “Save” button.

    Application name: The name of the application asking for consent. The name should accurately reflect your application and be consistent with the application name users see elsewhere. The application name will be shown on the Account Linking consent screen.

    Application logo: An image on the consent screen that will help users recognize your app. The logo is shown on Account linking consent screen and on account settings

    Support email: For users to contact you with questions about their consent.

    Scopes for Google APIs: Scopes allow your application to access your user's private Google data. For the Google Account Linking use case, default scope (email, profile, openid) is sufficient, you don’t need to add any sensitive scopes. It is generally a best practice to request scopes incrementally, at the time access is required, rather than up front. Learn more.

    Authorized domains: To protect you and your users, Google only allows applications that authenticate using OAuth to use Authorized Domains. Your applications' links must be hosted on Authorized Domains. Learn more.

    Application Homepage link: Home page for your application. Must be hosted on an Authorized Domain.

    Application Privacy Policy link: Shown on Google Account Linking consent screen. Must be hosted on an Authorized Domain.

    Application Terms of Service link (Optional): Must be hosted on an Authorized Domain.

    Figure 1. Google Account Linking Consent Screen for a fictitious Application, Tunery

  4. Check "Verification Status", if your application needs verification then click the "Submit For Verification" button to submit your application for verification. Refer to OAuth verification requirements for details.

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.

実装の検証

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. プラットフォームにリダイレクトされることを確認します。