モバイル&デスクトップ アプリ用 OAuth 2.0

このドキュメントでは、スマートフォン、タブレット、パソコンなどのデバイスにインストールされたアプリが、Google の OAuth 2.0 エンドポイントを使用して YouTube Data API へのアクセスを承認する方法について説明します。

OAuth 2.0 では、ユーザー名やパスワードなどの情報を秘密にしたまま、ユーザーが特定のデータをアプリケーションと共有できます。たとえば、アプリケーションは OAuth 2.0 を使用して、ユーザーの YouTube チャンネルに動画をアップロードする権限を取得できます。

インストールされたアプリは個々のデバイスに配布され、これらのアプリはシークレットを保持できないと想定されています。ユーザーがアプリを使用しているときや、アプリがバックグラウンドで実行されているときに、Google API にアクセスできます。

この認証フローは、ウェブ サーバー アプリケーションで使用されるものと似ています。主な違いは、インストールされたアプリがシステム ブラウザを開き、Google の認証サーバーからのレスポンスを処理するためのローカル リダイレクト URI を指定する必要があることです。

ライブラリとサンプル

iOS アプリの場合は、 Google でログイン iOS SDK の最新バージョンを使用することをおすすめします。この SDK はユーザー認証を処理し、このガイドで説明する下位レベルのプロトコルよりも実装が簡単です。

システム ブラウザをサポートしていないデバイスや、テレビ、ゲーム機、カメラ、プリンタなど入力機能が制限されているデバイスで実行されるアプリについては、TV&デバイス用 OAuth 2.0 または テレビと入力機能が限られたデバイスでのログインをご覧ください。

前提条件

プロジェクトでAPI を有効にする

Google API を呼び出すアプリケーションは、API Console でそれらの API を有効にする必要があります。

プロジェクトで API を有効にするには:

  1. Google API Console で API ライブラリを開きます
  2. プロンプトが表示されたら、プロジェクトのいずれかを選択するか、新しいプロジェクトを作成します。
  3. [ライブラリ] ページで、YouTube Data API を見つけて有効にします。アプリケーションで使用する他の API を見つけて、それらも有効にします。

承認認証情報を作成する

OAuth 2.0 を使用して Google API にアクセスするアプリケーションは、Google の OAuth 2.0 サーバーに対して自身の身元を示す認証情報を持つ必要があります。次の手順では、プロジェクトの認証情報を作成する方法について説明します。アプリケーションは、この認証情報を使用して、プロジェクトで有効にした API にアクセスできます。

  1. [クライアント] ページに移動します。
  2. [クライアントの作成] をクリックします。
  3. 以降のセクションでは、Google の認可サーバーがサポートするクライアント タイプについて説明します。アプリケーションに推奨されるクライアント タイプを選択し、OAuth クライアントに名前を付け、フォームの他のフィールドを適宜設定します。
iOS
  1. アプリケーションの種類として [iOS] を選択します。
  2. OAuth クライアントの名前を入力します。この名前は、プロジェクトのクライアント ページに表示され、クライアントを識別するために使用されます。
  3. アプリのバンドル識別子を入力します。バンドル ID は、アプリの情報プロパティ リスト リソース ファイル(info.plist)の CFBundleIdentifier キーの値です。この値は、Xcode プロジェクト エディタの [General] ペインまたは [Signing & Capabilities] ペインに表示されることがほとんどです。バンドル ID は、Apple の App Store Connect サイトのアプリの [App Information] ページの [General Information] セクションにも表示されます。

    App Check 機能を使用している場合は、アプリの正しいバンドル ID を使用していることを確認してください。この ID は変更できません。

  4. (省略可)

    アプリが Apple の App Store で公開されている場合は、アプリの App Store ID を入力します。ストア ID は、すべての Apple App Store URL に含まれる数字の文字列です。

    1. iOS または iPadOS デバイスで Apple App Store アプリを開きます。
    2. アプリを検索します。
    3. 共有ボタン(四角と上向き矢印の記号)を選択します。
    4. [リンクをコピー] を選択します。
    5. リンクをテキスト エディタに貼り付けます。App Store ID は URL の末尾部分です。

      例: https://apps.apple.com/app/google/id284815942

  5. (省略可)

    チーム ID を入力します。詳しくは、Apple Developer アカウントのドキュメントのチーム ID を確認するをご覧ください。

    注: クライアントで App Check を有効にする場合は、[チーム ID] フィールドが必要です。
  6. (省略可)

    iOS アプリで App Check を有効にします。App Check を有効にすると、Apple の App Attest サービスを使用して、OAuth クライアントから送信された OAuth 2.0 リクエストが正規のものであり、アプリから送信されたものであることを確認します。これにより、アプリのなりすましのリスクを軽減できます。iOS アプリで App Check を有効にする方法の詳細をご覧ください。

  7. [作成] をクリックします。
UWP
  1. [ユニバーサル Windows プラットフォーム] アプリケーションの種類を選択します。
  2. OAuth クライアントの名前を入力します。この名前は、クライアントを識別するためにプロジェクトの に表示されます。
  3. アプリの 12 文字の Microsoft Store ID を入力します。この値は、Microsoft パートナー センターの [アプリ管理] セクションにある [アプリ ID] ページで確認できます。
  4. [作成] をクリックします。

UWP アプリの場合、リダイレクト URI は、アプリケーションの一意のパッケージ セキュリティ識別子(SID)を使用して形成されます。アプリの Package SID は、Visual Studio プロジェクト内の Package.appxmanifest ファイルにあります。

Google Cloud コンソールでクライアント ID を作成するときは、パッケージ SID の小文字の値を使用して、次の形式でリダイレクト URI を指定する必要があります。

ms-app://YOUR_APP_PACKAGE_SID

UWP アプリの場合、カスタム URI スキームは Microsoft のドキュメントで指定されているように、39 文字以下にする必要があります。

アクセス スコープを特定する

スコープを指定すると、アプリケーションからのアクセス要求は必要なリソースのみに限定されるようになり、ユーザーはアプリケーションに付与するアクセスレベルを制御できます。そのため、リクエストされるスコープの数とユーザーの同意を得られる可能性の間には逆相関がある可能性があります。

OAuth 2.0 認証の実装を開始する前に、アプリがアクセス権限を必要とするスコープを設定しておくことをおすすめします。

<0

YouTube Data API v3 では、次のスコープが使用されます。

範囲 説明
https://www.googleapis.com/auth/youtube YouTube アカウントの管理
https://www.googleapis.com/auth/youtube.channel-memberships.creator 現在アクティブなチャンネル メンバー、メンバーの現在のレベル、いつメンバーになったかをリストで確認できます。
https://www.googleapis.com/auth/youtube.force-ssl YouTube 動画、評価、コメント、字幕の表示、編集、完全削除
https://www.googleapis.com/auth/youtube.readonly YouTube アカウントの表示
https://www.googleapis.com/auth/youtube.upload YouTube 動画の管理
https://www.googleapis.com/auth/youtubepartner YouTube のアセットや関連するコンテンツの表示と管理
https://www.googleapis.com/auth/youtubepartner-channel-audit YouTube パートナーの監査プロセス時に関連する YouTube チャンネルの個人情報の表示

OAuth 2.0 API スコープのドキュメントには、Google API へのアクセスに使用できるスコープの完全なリストが記載されています。

OAuth 2.0 アクセス トークンの取得

次の手順は、アプリケーションが Google の OAuth 2.0 サーバーと連携して、ユーザーに代わって API リクエストを実行するためのユーザーの同意を得る方法を示しています。ユーザーの承認が必要な Google API リクエストを実行するには、アプリがその同意を得ている必要があります。

ステップ 1: コード検証ツールとチャレンジを生成する

Google は、インストール済みのアプリのフローをより安全にするために、Proof Key for Code Exchange(PKCE)プロトコルをサポートしています。認可リクエストごとに一意のコード検証ツールが作成され、その変換された値(code_challenge)が認可サーバーに送信されて認証コードが取得されます。

コード検証ツールを作成する

code_verifier は、予約されていない文字 [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" を使用した高エントロピーの暗号論的ランダム文字列です。最小長は 43 文字、最大長は 128 文字です。

コード検証ツールは、値を推測することが現実的でないほどのエントロピーを備えている必要があります。

コードチャレンジを作成する

コードチャレンジの作成方法は 2 つあります。

コードチャレンジの生成方法
S256(推奨) コードチャレンジは、コード検証ツールの Base64URL(パディングなし)でエンコードされた SHA256 ハッシュです。
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
plain コードチャレンジは、上記で生成されたコード検証ツールと同じ値です。
code_challenge = code_verifier

ステップ 2: Google の OAuth 2.0 サーバーにリクエストを送信する

ユーザーの承認を取得するには、https://accounts.google.com/o/oauth2/v2/auth の Google の認可サーバーにリクエストを送信します。このエンドポイントは、アクティブなセッションのルックアップを処理し、ユーザーを認証して、ユーザーの同意を取得します。このエンドポイントは SSL 経由でのみアクセス可能で、HTTP(非 SSL)接続は拒否されます。

認証サーバーは、インストール済みアプリに対して次のクエリ文字列パラメータをサポートしています。

パラメータ
client_id 必須

アプリケーションのクライアント ID。この値は、Cloud コンソールの [クライアント] ページで確認できます。

redirect_uri 必須

Google の認可サーバーがアプリにレスポンスを送信する方法を決定します。インストール済みアプリには複数のリダイレクト オプションがあり、特定のメソッドを念頭に置いて認可認証情報を設定する必要があります。

この値は、クライアントの Cloud コンソールのクライアント ページで構成した OAuth 2.0 クライアントの承認済みリダイレクト URI のいずれかと完全に一致する必要があります。この値が承認済みの URI と一致しない場合、redirect_uri_mismatch エラーが発生します。

次の表に、各メソッドの適切な redirect_uri パラメータ値を示します。

redirect_uri 個の値
カスタム URI スキーム com.example.app:redirect_uri_path

または

com.googleusercontent.apps.123:redirect_uri_path
  • com.example.app は、ユーザーが管理するドメインの逆引き DNS 表記です。カスタム スキームを有効にするには、ピリオドを含める必要があります。
  • com.googleusercontent.apps.123 は、クライアント ID の逆引き DNS 表記です。
  • redirect_uri_path は、/oauth2redirect などの省略可能なパス コンポーネントです。パスは 1 つのスラッシュで始まる必要があります。これは通常の HTTP URL とは異なります。
ループバック IP アドレス http://127.0.0.1:port または http://[::1]:port

プラットフォームに関連するループバック IP アドレスをクエリし、利用可能なランダムなポートで HTTP リスナーを起動します。port は、アプリがリッスンする実際のポート番号に置き換えます。

モバイルアプリでのループバック IP アドレス リダイレクト オプションのサポートは 非推奨になりました。

response_type 必須

Google OAuth 2.0 エンドポイントが認証コードを返すかどうかを決定します。

インストールされたアプリのパラメータ値を code に設定します。

scope 必須

ユーザーに代わってアプリケーションがアクセスできるリソースを識別するスコープのスペース区切りリスト。これらの値は、Google がユーザーに表示する同意画面に反映されます。

スコープを指定すると、アプリケーションからのアクセス要求は必要なリソースのみに限定されるようになり、ユーザーはアプリケーションに付与するアクセスレベルを制御できます。したがって、リクエストされるスコープの数とユーザーの同意が得られる可能性の間には逆相関があります。

YouTube Data API v3 では、次のスコープが使用されます。

範囲 説明
https://www.googleapis.com/auth/youtube YouTube アカウントの管理
https://www.googleapis.com/auth/youtube.channel-memberships.creator 現在アクティブなチャンネル メンバー、メンバーの現在のレベル、いつメンバーになったかをリストで確認できます。
https://www.googleapis.com/auth/youtube.force-ssl YouTube 動画、評価、コメント、字幕の表示、編集、完全削除
https://www.googleapis.com/auth/youtube.readonly YouTube アカウントの表示
https://www.googleapis.com/auth/youtube.upload YouTube 動画の管理
https://www.googleapis.com/auth/youtubepartner YouTube のアセットや関連するコンテンツの表示と管理
https://www.googleapis.com/auth/youtubepartner-channel-audit YouTube パートナーの監査プロセス時に関連する YouTube チャンネルの個人情報の表示

OAuth 2.0 API スコープのドキュメントには、Google API へのアクセスに使用できるスコープの完全なリストが記載されています。

code_challenge 推奨

認可コードの交換時にサーバーサイドのチャレンジとして使用されるエンコードされた code_verifier を指定します。詳細については、コードチャレンジを作成するをご覧ください。

code_challenge_method 推奨

認証コードの交換時に使用される code_verifier のエンコードに使用されたメソッドを指定します。このパラメータは、code_challenge パラメータと一緒に使用する必要があります。code_challenge を含むリクエストに code_challenge_method が含まれていない場合、code_challenge_method の値はデフォルトで plain になります。このパラメータでサポートされている値は S256 または plain のみです。

state 推奨

認証リクエストと認証サーバーのレスポンス間で状態を維持するためにアプリケーションが使用する任意の文字列値を指定します。ユーザーがアプリケーションのアクセス リクエストに同意または拒否すると、サーバーは送信した値を redirect_uri の URL フラグメント識別子(#)内の name=value ペアとして返します。

このパラメータは、ユーザーをアプリケーション内の正しいリソースに誘導する、ノンスを送信する、クロスサイト リクエスト フォージェリを軽減するなど、さまざまな目的に使用できます。redirect_uri は推測される可能性があるため、state 値を使用すると、受信接続が認証リクエストの結果であるという確実性を高めることができます。クライアントの状態をキャプチャする Cookie やその他の値のハッシュをエンコードしたり、ランダムな文字列を生成したりすると、レスポンスを検証して、リクエストとレスポンスが同じブラウザから発信されたことを確認できます。これにより、クロスサイト リクエスト フォージェリなどの攻撃から保護できます。state トークンを作成して確認する方法の例については、OpenID Connect のドキュメントをご覧ください。

login_hint 省略可

アプリが認証を試みているユーザーを把握している場合は、このパラメータを使用して Google 認証サーバーにヒントを提供できます。サーバーは、ログイン フォームのメール フィールドを事前入力するか、適切なマルチログイン セッションを選択することで、ヒントを使用してログイン フローを簡素化します。

パラメータ値を、ユーザーの Google ID に相当するメールアドレスまたは sub 識別子に設定します。

認証 URL の例

以下のタブは、さまざまなリダイレクト URI オプションの認証 URL の例を示しています。

各 URL は、ユーザーの YouTube アカウントを表示するためのアクセス権を付与するスコープへのアクセスをリクエストします。

redirect_uri パラメータの値を除いて、URL は同じです。URL には、必須の response_type パラメータと client_id パラメータ、オプションの state パラメータも含まれています。各 URL には、読みやすくするために改行とスペースが含まれています。

カスタム URI スキーム

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&
 response_type=code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken&
 redirect_uri=com.example.app%3A/oauth2redirect&
 client_id=client_id

ループバック IP アドレス

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&
 response_type=code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken&
 redirect_uri=http%3A//127.0.0.1%3A9004&
 client_id=client_id

ステップ 3: Google がユーザーに同意を求める

このステップでは、ユーザーがリクエストされたアクセス権限をアプリケーションに付与するかどうかを決定します。この段階で、Google は同意ウィンドウを表示します。このウィンドウには、アプリケーションの名前と、ユーザーの認証情報を使用してアクセス権限をリクエストしている Google API サービス、付与されるアクセス権限のスコープの概要が表示されます。ユーザーは、アプリケーションがリクエストした 1 つ以上のスコープへのアクセス権限を付与することに同意するか、リクエストを拒否できます。

この段階では、アプリケーションは何もする必要はありません。アクセスが許可されたかどうかを示す Google の OAuth 2.0 サーバーからのレスポンスを待機します。このレスポンスについては、次のステップで説明します。

エラー

Google の OAuth 2.0 認可エンドポイントへのリクエストで、想定される認証フローと認可フローではなく、ユーザー向けのエラー メッセージが表示されることがあります。一般的なエラーコードと推奨される解決策は次のとおりです。

admin_policy_enforced

Google アカウントは、Google Workspace 管理者のポリシーにより、リクエストされた 1 つ以上のスコープを承認できません。管理者がすべてのスコープまたは機密性の高い制限付きスコープへのアクセスを、OAuth クライアント ID に明示的に付与されるまで制限する方法について詳しくは、Google Workspace 管理者向けヘルプ記事の Google Workspace のデータにアクセスできるサードパーティ製アプリと内部アプリを制御するをご覧ください。

disallowed_useragent

認可エンドポイントは、Google の OAuth 2.0 ポリシーで禁止されている埋め込みユーザー エージェント内に表示されます。

iOS と macOS のデベロッパーは、WKWebView で認可リクエストを開く際にこのエラーが発生することがあります。デベロッパーは、代わりに Google ログイン for iOS や OpenID Foundation の AppAuth for iOS などの iOS ライブラリを使用する必要があります。

このエラーは、iOS または macOS アプリが埋め込みユーザー エージェントで一般的なウェブリンクを開き、ユーザーがサイトから Google の OAuth 2.0 認可エンドポイントに移動したときに発生することがあります。デベロッパーは、一般的なリンクがオペレーティング システムのデフォルトのリンク ハンドラ(ユニバーサル リンク ハンドラまたはデフォルトのブラウザアプリを含む)で開くようにする必要があります。SFSafariViewController ライブラリもサポートされているオプションです。

org_internal

リクエストの OAuth クライアント ID は、特定の Google Cloud 組織内の Google アカウントへのアクセスを制限するプロジェクトの一部です。この構成オプションの詳細については、OAuth 同意画面の設定に関するヘルプ記事のユーザータイプのセクションをご覧ください。

deleted_client

リクエストの作成に使用されている OAuth クライアントが削除されました。削除は手動で行われることも、未使用のクライアント の場合に自動で行われることもあります。削除されたクライアントは、削除から 30 日以内であれば復元できます。詳細 をご覧ください。

invalid_grant

コード検証ツールとチャレンジを使用している場合、code_callenge パラメータが無効であるか、指定されていません。code_challenge パラメータが正しく設定されていることを確認します。

アクセス トークンを更新する場合、トークンの有効期限が切れているか、無効になっている可能性があります。ユーザーを再度認証し、新しいトークンを取得するためのユーザーの同意を求めます。このエラーが引き続き表示される場合は、アプリケーションが正しく構成されていること、リクエストで正しいトークンとパラメータを使用していることを確認してください。それ以外の場合は、ユーザー アカウントが削除または無効になっている可能性があります。

redirect_uri_mismatch

認証リクエストで渡された redirect_uri が、OAuth クライアント ID の承認済みリダイレクト URI と一致しません。Google Cloud コンソールの [クライアント] ページで、承認済みリダイレクト URI を確認してください。

渡された redirect_uri は、クライアント タイプに対して無効である可能性があります。

redirect_uri パラメータは、非推奨となりサポートが終了した OAuth 帯域外(OOB)フローを参照している可能性があります。移行ガイドを参照して、統合を更新してください。

invalid_request

リクエストに問題がありました。これには、次のような理由が考えられます。

  • リクエストの形式が正しくありませんでした
  • リクエストに必須パラメータが含まれていませんでした
  • リクエストで、Google がサポートしていない認証方法が使用されています。OAuth 統合で推奨される統合方法が使用されていることを確認する
  • リダイレクト URI にサポートされていないカスタム スキームが使用されました。 Android または Chrome アプリでカスタム URI スキームがサポートされていませんというエラー メッセージが表示された場合は、カスタム URI スキームの代替手段についてこちらをご覧ください。

ステップ 4: OAuth 2.0 サーバーのレスポンスを処理する

アプリケーションが認証レスポンスを受信する方法は、使用するリダイレクト URI スキームによって異なります。スキームに関係なく、レスポンスには認証コード(code)またはエラー(error)が含まれます。たとえば、error=access_denied は、ユーザーがリクエストを拒否したことを示します。

ユーザーがアプリへのアクセスを許可すると、次のステップで説明するように、認証コードをアクセス トークンと更新トークンに交換できます。

ステップ 5: 認証コードを更新トークンとアクセス トークンに交換する

認可コードをアクセス トークンと交換するには、https://oauth2.googleapis.com/token エンドポイントを呼び出し、次のパラメータを設定します。

フィールド
client_id Cloud コンソールの [クライアント] ページから取得したクライアント ID。
client_secret 省略可

Cloud Console のクライアント ページから取得したクライアント シークレット。

code 初回リクエストから返された認証コード。
code_verifier 手順 1 で作成したコード検証ツール。
grant_type OAuth 2.0 仕様で定義されているように、このフィールドの値は authorization_code に設定する必要があります。
redirect_uri 指定された client_id の Cloud Console の [クライアント] ページに表示されているプロジェクトのリダイレクト URI のいずれか。

DPoP の使用は任意ですが、セキュリティ強化のためにおすすめします。DPoP のセキュリティは、秘密鍵が単一のデバイスに制限されていることに依存します。TPM、セキュア エンクレーブ、その他のハードウェア格納型キーストアなどを使用して、デバイス外にコピーできない方法で保存することをおすすめします。 DPoP を使用するには、トークン エンドポイントへのリクエストごとに新しい一意の DPoP 証明 JWT を生成し、HTTP リクエスト ヘッダーとして追加する必要があります。

ヘッダー 必須 説明
DPoP 省略可 DPoP 証明は、秘密鍵の所有を証明する JWT です。これはパラメータではなくヘッダーです。指定されている場合、返されるトークンはこのキーにバインドされます。リクエストごとに新しい一意の証明を生成し、リクエストと一致する htm(HTTP メソッド)と htu(HTTP URI)のクレームを含める必要があります。

次のスニペットは、リクエストの例を示しています。

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
 VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
 nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
 QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
 oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
 WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
redirect_uri=http://127.0.0.1:9004&
grant_type=authorization_code

DPoP 証明を構築する

次の手順では、コマンドラインから OpenSSL を使用して DPoP 証明を作成する方法を示します。

  1. EC P-256 鍵ペアを生成します。
    openssl ecparam -name prime256v1 -genkey -noout -out dpop_private.pem
    openssl ec -in dpop_private.pem -pubout -out dpop_public.pem
  2. DPoP ヘッダーを作成します。

    ヘッダーには、typalgjwk(公開鍵)のクレームを含める必要があります。xy の値は、EC 公開鍵の Base64Url エンコードされた座標です。次の JSON を Base64Url でエンコードします。

    {
      "typ":"dpop+jwt",
      "alg":"ES256",
      "jwk": {
        "kty":"EC",
        "x":"YOUR_PUBLIC_KEY_X",
        "y":"YOUR_PUBLIC_KEY_Y",
        "crv":"P-256"
      }
    }
  3. DPoP ペイロードを作成します。

    ペイロードには、jti(リクエストの一意の識別子)、htm(HTTP メソッド(POST など))、htu(HTTP URI(https://oauth2.googleapis.com/token など))、iat(発行時刻)を含める必要があります。以前のリクエストに対するレスポンスの DPoP-Nonce ヘッダーでサーバーからノンスを受け取った場合は、そのノンス値を nonce クレームに含める必要があります。ノンス クレームは認可コード交換では省略可能で、DPoP-Nonce ヘッダーが以前に受信された場合にのみ使用されます。この JSON を Base64Url でエンコードします。

    {
      "jti":"JTI_VALUE",
      "htm":"POST",
      "htu":"https://oauth2.googleapis.com/token",
      "iat":YOUR_JWT_ISSUED_TIME,
      "nonce":"SERVER_PROVIDED_NONCE"
    }

    jti の値は、エクスチェンジのタイプによって異なります。

    • 認証コードの交換の場合、jti は認証コードの Base64Url エンコードされた SHA256 ハッシュ("jti":"BASE64URL(SHA256(AUTHORIZATION_CODE))")である必要があります。
    • 更新トークンの交換の場合、jti はリクエストごとに一意の識別子("jti":"YOUR_UNIQUE_PER_REQUEST_IDENTIFIER")である必要があります。
  4. 証明に署名します。

    エンコードされたヘッダーとペイロードをピリオド(.)で連結し、ES256 を使用して秘密鍵で結果に署名します。JWS では、署名が未加工の R | S 連結形式(P-256 の場合は 64 バイト)である必要があります。OpenSSL を直接使用する場合は、デフォルトの ASN.1 DER エンコード署名をこの未加工形式に変換する必要があります。

交換が成功すると、トークンを含む 200 OK レスポンスが返されます。交換時に有効な DPoP 証明書が使用された場合、Google が返す更新トークンはキーに DPoP バインドされますが、アクセス トークンは DPoP バインドされません。アクセス トークンは DPoP ではなく Bearertoken_type を保持します。また、Google はレスポンスで DPoP-Nonce HTTP ヘッダーを返します。クライアントはこのノンスをキャッシュに保存し、後続のリクエスト(更新トークンを新しいアクセス トークンと交換するときや、DPoP で保護された API を呼び出すときなど)の DPoP 証明書の nonce クレームに含める必要があります。この早期発行されたノンスを使用することで、次のリクエストで余分なラウンド トリップの失敗(use_dpop_nonce)を回避できます。

DPoP バインド リフレッシュ トークンを使用して行われたトークン交換リクエストには、DPoP 証明を含める必要があります。

DPoP ヘッダーが想定どおりに存在しないか、無効であるか、証明がトークンにバインドされている鍵とは異なる鍵を使用している場合、交換の失敗が発生します。このような場合、サーバーは 400 Bad Request エラーを返します。DPoP 証明に htm または htu クレームの不一致、iat の有効期限切れ、jti の再利用、無効な署名がある場合、Google は invalid_dpop_proof エラーコードを返します。更新トークンの交換時など、DPoP ノンスが必要な場合に、DPoP 証明書に nonce クレームがないか、ノンス値がサーバーで受け入れられない(期限切れ、すでに使用済み、正しくないなど)場合、Google は use_dpop_nonce エラーコードと、後続のリクエストで使用できる新しいノンスを含む DPoP-Nonce HTTP ヘッダーを返します。他の障害では invalid_grant が返されることがあります。

Google は、このリクエストに応答して、有効期間の短いアクセス トークンと更新トークンを含む JSON オブジェクトを返します。

レスポンスには、次のフィールドが含まれます。

フィールド
access_token Google API リクエストを承認するためにアプリケーションが送信するトークン。
expires_in アクセス トークンの残りの有効期間(秒単位)。
id_token 注: このプロパティは、リクエストに openidprofileemail などの ID スコープが含まれている場合にのみ返されます。値は、ユーザーに関するデジタル署名付き ID 情報を含む JSON ウェブトークン(JWT)です。
refresh_token 新しいアクセス トークンを取得するために使用できるトークン。更新トークンは、ユーザーがアクセスを取り消すか、更新トークンの有効期限が切れるまで有効です。DPoP が使用された場合、更新トークンは DPoP 証明の署名に使用された秘密鍵にバインドされます。インストールされたアプリケーションに対しては、常にリフレッシュ トークンが返されることに注意してください。
refresh_token_expires_in 更新トークンの残りの有効期間(秒単位)。この値は、ユーザーが時間ベースのアクセスを許可した場合にのみ設定されます。
scope access_token によって付与されたアクセス権のスコープ。スペース区切りの大文字と小文字が区別される文字列のリストとして表されます。
token_type 返されるトークンのタイプ。この値は、DPoP が使用されている場合でも常に Bearer です。

次のスニペットは、DPoP が使用されている場合の成功したレスポンス ヘッダーと本文のサンプルを示しています。

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/youtube.force-ssl",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

ステップ 6: ユーザーがどのスコープを付与したかを確認する

複数の権限(スコープ)をリクエストする場合、ユーザーがアプリにすべての権限へのアクセスを許可しないことがあります。アプリは、実際に付与されたスコープを確認し、一部の権限が拒否された状況に適切に対応する必要があります。通常は、拒否されたスコープに依存する機能を無効にします。

ただし、例外もあります。ドメイン全体の権限の委任が設定されている Google Workspace Enterprise アプリ、または [信頼できる] とマークされているアプリは、詳細な権限の同意画面を省略します。これらのアプリでは、ユーザーにきめ細かい権限の同意画面は表示されません。代わりに、アプリはリクエストされたすべてのスコープを受け取るか、1 つも受け取らないかのどちらかになります。

詳しくは、きめ細かい権限を処理する方法をご覧ください。

ユーザーが特定のスコープへのアクセス権をアプリケーションに付与しているかどうかを確認するには、アクセス トークン レスポンスの scope フィールドを調べます。access_token によって付与されたアクセス権のスコープ。スペース区切りの大文字と小文字が区別される文字列のリストとして表現されます。

たとえば、次のアクセス トークン レスポンスの例は、ユーザーがアプリに YouTube 動画、評価、コメント、字幕の表示、編集、完全削除の権限を付与したことを示しています。

  {
    "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
    "expires_in": 3920,
    "token_type": "Bearer",
    "scope": "https://www.googleapis.com/auth/youtube.force-ssl",
    "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
  }

Google API を呼び出す

アプリケーションがアクセス トークンを取得したら、API で必要なアクセス スコープが承認されている場合、トークンを使用して特定のユーザー アカウントの代わりに Google API を呼び出すことができます。これを行うには、access_token クエリ パラメータまたは Authorization HTTP ヘッダー Bearer 値のいずれかを含めることで、API へのリクエストにアクセス トークンを含めます。クエリ文字列はサーバーログに表示される傾向があるため、可能な場合は HTTP ヘッダーを使用することをおすすめします。ほとんどの場合、クライアント ライブラリを使用して Google API への呼び出しを設定できます(たとえば、YouTube Data API を呼び出す場合など)。

YouTube Data API は、レコード レーベルや映画スタジオなど、複数の YouTube チャンネルを所有して管理している YouTube コンテンツ所有者に対してのみサービス アカウントをサポートします。

OAuth 2.0 Playground では、すべての Google API を試して、そのスコープを確認できます。

HTTP GET の例

Authorization: Bearer HTTP ヘッダーを使用して youtube.channels エンドポイント(YouTube Data API)を呼び出すと、次のようになります。独自のアクセス トークンを指定する必要があります。

GET /youtube/v3/channels?part=snippet&mine=true HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

以下は、access_token クエリ文字列パラメータを使用して、認証済みユーザーに対して同じ API を呼び出す例です。

GET https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true

curl の例

これらのコマンドは、curl コマンドライン アプリケーションでテストできます。HTTP ヘッダー オプション(推奨)を使用する例を次に示します。

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true

または、クエリ文字列パラメータ オプションを使用します。

curl https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true

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

アクセス トークンは定期的に期限が切れ、関連する API リクエストに対して無効な認証情報になります。トークンに関連付けられたスコープへのオフライン アクセスをリクエストした場合は、ユーザーに権限を求めることなく(ユーザーが不在の場合を含めて)アクセス トークンを更新できます。

アクセス トークンを更新するには、アプリケーションが HTTPS POST リクエストを Google の認証サーバー(https://oauth2.googleapis.com/token)に送信します。このリクエストの本文には次のパラメータが含まれます。

名前
client_id API Console から取得したクライアント ID。
client_secret 省略可

API Console から取得したクライアント シークレット。(client_secret は、Android、iOS、Chrome アプリケーションとして登録されたクライアントからのリクエストには適用されません)。

grant_type OAuth 2.0 仕様で定義されているように、このフィールドの値は refresh_token に設定する必要があります。
refresh_token 認証コード交換から返された更新トークン。

DPoP の使用は任意ですが、セキュリティ強化のためにおすすめします。更新トークンで DPoP を使用するには、トークン エンドポイントへのリクエストごとに新しい一意の DPoP 証明 JWT を生成する必要があります。この証明は、最初の認可コード交換で使用されたのと同じ秘密鍵で署名する必要があります。アプリケーションは、証明を HTTP リクエスト ヘッダーとして追加します。

ヘッダー 必須 説明
DPoP 省略可 DPoP 証明は、秘密鍵の所有を証明する JWT です。これはパラメータではなくヘッダーです。指定されている場合、返されるトークンはこのキーにバインドされます。リクエストごとに新しい一意の証明を生成し、リクエストと一致する htm(HTTP メソッド)と htu(HTTP URI)のクレームを含める必要があります。

次のスニペットは、リクエストの例を示しています。

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
DPoP: DPOP_PROOF_JWT

client_id=your_client_id&
refresh_token=refresh_token&
grant_type=refresh_token

更新トークンで DPoP を使用するには、リクエスト用に新しい一意の DPoP 証明 JWT を生成する必要があります。鍵ペアの生成と JWT の構築に関する手順については、DPoP 証明を構築するをご覧ください。

交換が成功すると、新しいアクセス トークンを含む 200 OK レスポンスが返されます。DPoP を使用する場合、token_typeBearer です。成功レスポンスは、更新トークンの DPoP 証明が受け入れられたことを確認します。Google はレスポンスで新しい DPoP-Nonce HTTP ヘッダーを返すこともあります。返された場合、クライアントはこのノンスをキャッシュに保存し、後続のリクエストの DPoP 証明の nonce クレームに含める必要があります。

DPoP ヘッダーがないか、無効であるか、間違ったキーを使用している場合、エクスチェンジが失敗します。特定の DPoP エラーコードとノンスの処理の詳細については、交換の失敗をご覧ください。

次のスニペットは、DPoP が使用されている場合の成功したレスポンス ヘッダーと本文のサンプルを示しています。

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
  "token_type": "Bearer"
}

発行される更新トークンの数には制限があります。クライアントとユーザーの組み合わせごとに 1 つの制限、すべてのクライアントにわたるユーザーごとに 1 つの制限です。更新トークンは長期保存に保存し、有効な限り使用し続ける必要があります。アプリケーションが過剰な数の更新トークンをリクエストすると、これらの制限に達し、古い更新トークンが機能しなくなる可能性があります。

トークン失効

ユーザーがアプリに付与したアクセス権を取り消したい場合もあります。ユーザーは、 アカウント設定にアクセスしてアクセス権を取り消すことができます。詳しくは、アカウントにアクセスできるサードパーティのサイトやアプリのサポート ドキュメントの「サイトやアプリのアクセス権を削除する」セクションをご覧ください。

アプリケーションがプログラムで付与されたアクセス権を取り消すこともできます。プログラムによる取り消しは、ユーザーが登録を解除した場合、アプリケーションを削除した場合、アプリに必要な API リソースが大幅に変更された場合などに重要です。つまり、削除プロセスの一部として、以前にアプリケーションに付与された権限が削除されるように API リクエストを含めることができます。

プログラムでトークンを取り消すには、アプリケーションが https://oauth2.googleapis.com/revoke にリクエストを送信し、トークンをパラメータとして含めます。

curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
        https://oauth2.googleapis.com/revoke?token={token}

トークンはアクセス トークンまたは更新トークンです。トークンがアクセス トークンで、対応する更新トークンがある場合、更新トークンも取り消されます。

取り消しが正常に処理されると、レスポンスの HTTP ステータス コードは 200 になります。エラー条件の場合、エラーコードとともに HTTP ステータス コード 400 が返されます。

アプリのリダイレクト方法

カスタム URI スキーム

カスタム URI スキームは、カスタム定義のスキームを使用してアプリを開くディープリンクの一種です。

Chrome アプリでカスタム URI スキームを使用する代替手段

Chrome Identity API を使用します。この API は OAuth 2.0 レスポンスをアプリに直接配信するため、リダイレクト URI は不要になります。

ループバック IP アドレス(macOS、Linux、Windows デスクトップ)

この URL を使用して認証コードを受け取るには、アプリケーションがローカル ウェブサーバーでリッスンしている必要があります。これは多くのプラットフォームで可能ですが、すべてのプラットフォームで可能というわけではありません。ただし、プラットフォームがサポートしている場合は、これが認証コードを取得するための推奨メカニズムです。

アプリが認証レスポンスを受け取ったら、ユーザーにブラウザを閉じてアプリに戻るよう指示する HTML ページを表示して応答するのが、ユーザビリティの面で最適です。

推奨される使い方 macOS、Linux、Windows のデスクトップ アプリ(ユニバーサル Windows プラットフォーム アプリを除く)
フォームの値 アプリケーション タイプを [デスクトップ アプリ] に設定します。

手動コピー/貼り付け(非推奨)

アプリを保護する

Chrome でアプリの所有権を確認する

アプリケーションの所有権を確認することで、アプリのなりすましのリスクを軽減できます。

確認手続きを完了するには、Chrome ウェブストア デベロッパー アカウントを使用します。 確認手続きを完了するには、次の要件を満たす必要があります。

  • Chrome ウェブストア デベロッパー ダッシュボードに、確認を完了する Chrome 拡張機能 OAuth クライアントと同じ商品アイテム ID のアイテムが登録されている必要があります。
  • Chrome ウェブストア アイテムのパブリッシャーである必要があります。Chrome ウェブストア デベロッパー ダッシュボードでのアクセス管理について詳しくは、こちらをご覧ください。

Chrome 拡張機能クライアントの [Verify App Ownership] セクションで、[Verify Ownership] ボタンをクリックして確認プロセスを完了します。

注: アカウントへのアクセス権を付与した後、検証プロセスを完了するまでに数分待ちます。

確認が成功すると、確認プロセスの成功を確認する通知が表示されます。それ以外の場合は、エラー プロンプトが表示されます。

確認に失敗した場合は、次の手順をお試しください。

  • 確認を完了する Chrome 拡張機能 OAuth クライアントと同じ商品アイテム ID のアイテムが Chrome ウェブストア デベロッパー ダッシュボードに登録されていることを確認します。
  • アプリのパブリッシャーであることを確認します。つまり、アプリの個人パブリッシャーであるか、アプリのグループ投稿者のメンバーである必要があります。Chrome ウェブストア デベロッパー ダッシュボードのアクセス管理について詳しくは、こちらをご覧ください。
  • グループ投稿者リストを更新したばかりの場合は、Chrome ウェブストア デベロッパー ダッシュボードでグループ投稿者メンバーシップ リストが同期されていることを確認します。パブリッシャーのメンバーシップ リストの同期について詳しくは、こちらをご覧ください。

App Check(iOS のみ)

App Check 機能は、Apple の App Attest サービスを使用して、Google OAuth 2.0 エンドポイントに対するリクエストが正規のアプリから発信されたものであることを確認することで、iOS アプリを不正使用から保護します。これにより、アプリのなりすましのリスクを軽減できます。

iOS クライアントで App Check を有効にする

iOS クライアントで App Check を有効にするには、次の要件を満たす必要があります。
  • iOS クライアントのチーム ID を指定する必要があります。
  • バンドル ID にはワイルドカードを使用しないでください。複数のアプリに解決される可能性があるためです。つまり、バンドル ID にはアスタリスク(*)記号を含めないでください。
App Check を有効にするには、iOS クライアントの編集ビューで [Firebase App Check を使用して OAuth クライアントを不正行為から保護する] 切り替えボタンをオンにします。

App Check を有効にすると、OAuth クライアントの編集ビューに、クライアントからの OAuth リクエストに関連する指標が表示されるようになります。App Check を適用するまで、未確認のソースからのリクエストはブロックされません。指標モニタリング ページの情報は、強制適用を開始するタイミングを判断するのに役立ちます。

iOS アプリで App Check を有効にすると、App Check 機能に関連するエラーが表示されることがあります。これらのエラーを解決するには、次の手順をお試しください。

  • 指定したバンドル ID とチーム ID が有効であることを確認します。
  • バンドル ID にワイルドカードを使用していないことを確認します。

iOS クライアントに App Check を適用する

アプリで App Check を有効にしても、認識されないリクエストが自動的にブロックされることはありません。この保護を適用するには、iOS クライアントの編集ビューに移動します。ページの右側の [Google Identity for iOS] セクションに、App Check の指標が表示されます。指標には次の情報が含まれます。
  • 確認済みのリクエスト数 - 有効な App Check トークンを含むリクエスト。App Check の適用を有効にすると、このカテゴリのリクエストのみが成功します。
  • 未検証のリクエスト数: 古いクライアント リクエストの可能性 - App Check トークンがないリクエスト。これらのリクエストは、App Check の実装が含まれていない古いバージョンのアプリから送信された可能性があります。
  • 未検証のリクエスト数: 送信元が不明なリクエスト - App Check トークンがなく、アプリから送信されていないと思われるリクエスト。
  • 未検証のリクエスト数: 無効なリクエスト - 無効な App Check トークンを含むリクエスト。お客様のアプリになりすまそうと試みている偽のクライアント、またはエミュレートされた環境からのものである可能性があります。
これらの指標を確認して、App Check の適用がユーザーに与える影響を把握します。

App Check を適用するには、[ENFORCE] ボタンをクリックして、選択内容を確定します。適用が有効になると、クライアントからの未検証のリクエストはすべて拒否されます。

: 適用を有効にした後、変更が有効になるまでに最大 15 分かかることがあります。

iOS クライアントの App Check の適用を解除する

アプリの App Check の適用を解除すると、適用が停止し、未検証のリクエストを含め、クライアントから Google OAuth 2.0 エンドポイントへのすべてのリクエストが許可されます。

iOS クライアントの App Check を適用しないようにするには、iOS クライアントの編集ビューに移動して、[適用しない] ボタンをクリックし、選択内容を確認します。

: App Check の適用を解除した後、変更が反映されるまでに最大 15 分かかることがあります。

iOS クライアントの App Check を無効にする

アプリの App Check を無効にすると、すべての App Check モニタリングと適用が停止します。代わりに App Check の適用を解除して、クライアントの指標のモニタリングを続行することを検討してください。

iOS クライアントの App Check を無効にするには、iOS クライアントの編集ビューに移動し、[Firebase App Check を使用して OAuth クライアントを不正行為から保護する] 切り替えボタンをオフにします。

: App Check を無効にした後、変更が反映されるまでに最大 15 分かかることがあります。

時間ベースのアクセス

時間ベースのアクセスでは、ユーザーはアクションを完了するために、アプリにデータへのアクセスを期間限定で許可できます。時間ベースのアクセスは、同意フローの特定の Google サービスで利用でき、ユーザーは期間限定でアクセスを許可できます。たとえば、 Data Portability API を使用すると、データを 1 回だけ転送できます。

ユーザーがアプリケーションに時間ベースのアクセス権を付与すると、更新トークンは指定された期間の後に期限切れになります。特定の状況下では、更新トークンが早期に無効になることがあります。詳しくは、こちらのケースをご覧ください。このような場合、認可コード交換レスポンスで返される refresh_token_expires_in フィールドは、更新トークンの有効期限が切れるまでの残り時間を表します。

関連情報

IETF のベスト カレント プラクティス OAuth 2.0 for Native Apps では、ここで説明するベスト プラクティスの多くが確立されています。

クロスアカウント保護機能を実装する

ユーザーのアカウントを保護するために追加で実施すべき手順は、Google のクロスアカウント保護サービスを利用してクロスアカウント保護機能を実装することです。このサービスを利用すると、セキュリティ イベントの通知を登録して、ユーザー アカウントの大きな変更に関する情報をアプリに提供できます。その後、イベントへの対応方法に応じて、この情報を使用してアクションを実行できます。

Google のクロスアカウント保護機能によってアプリに送信されるイベントタイプの例を次に示します。

  • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
  • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
  • https://schemas.openid.net/secevent/risc/event-type/account-disabled

クロスアカウント保護の実装方法と利用可能なイベントの完全なリストについては、 クロスアカウント保護機能でユーザー アカウントを保護する をご覧ください。