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 を返します。
userinfo リクエストを処理する

userinfo エンドポイントは、OAuth 2.0 で保護されたリソースで、リンクされたユーザーに関するクレームを返します。userinfo エンドポイントの実装とホストは任意ですが、以下のユースケースを除きます。

トークン エンドポイントからアクセス トークンが正常に取得されると、Google は、リンクされたユーザーに関する基本的なプロフィール情報を取得するためのリクエストを userinfo エンドポイントに送信します。

userinfo エンドポイント リクエスト ヘッダー
Authorization header Bearer タイプのアクセス トークン。

たとえば、userinfo エンドポイントが https://myservice.example.com/userinfo の場合、リクエストは次のようになります。

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

userinfo エンドポイントでリクエストを処理するには、次の手順を行います。

  1. Authorization ヘッダーからアクセス トークンを抽出し、そのアクセス トークンに関連付けられたユーザーの情報を返します。
  2. アクセス トークンが無効な場合は、WWW-Authenticate レスポンス ヘッダーを使用して HTTP 401 Unauthorized エラーを返します。userinfo エラー レスポンスの例を次に示します。
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: error="invalid_token",
    error_description="The Access Token expired"
    
    リンク処理中に 401 Unauthorized またはその他の失敗したエラー レスポンスが返された場合、そのエラーは修復不能となり、取得したトークンは破棄されるため、ユーザーはリンク処理をやり直す必要があります。
  3. アクセス トークンが有効な場合は、HTTPS の本文に次の JSON オブジェクトを含む HTTP 200 レスポンスを返します。 レスポンス:

    {
    "sub": "USER_UUID",
    "email": "EMAIL_ADDRESS",
    "given_name": "FIRST_NAME",
    "family_name": "LAST_NAME",
    "name": "FULL_NAME",
    "picture": "PROFILE_PICTURE",
    }
    userinfo エンドポイントが HTTP 200 成功レスポンスを返すと、取得したトークンとクレームがユーザーの Google アカウントに登録されます。

    userinfo エンドポイント レスポンス
    sub システム内でユーザーを識別する一意の ID。
    email ユーザーのメールアドレス。
    given_name 省略可: ユーザーの名。
    family_name 省略可: ユーザーの姓。
    name 省略可: ユーザーの氏名。
    picture 省略可: ユーザーのプロフィール写真。

実装の検証

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