テレビや制限付き入力デバイス アプリケーション用の OAuth 2.0

このドキュメントでは、テレビ、ゲーム機、プリンタなどのデバイスで実行されているアプリケーションを介して YouTube Data API にアクセスするための OAuth 2.0 認証を実装する方法について説明します。具体的には、このフローは、ブラウザにアクセスできないデバイスまたは入力機能が限られているデバイス向けに設計されています。

OAuth 2.0 では、ユーザー名やパスワードなどの情報を秘密にしたまま、ユーザーが特定のデータをアプリケーションと共有できます。 たとえば、TV アプリは OAuth 2.0 を使用して、Google ドライブに保存されているファイルを選択する権限を取得できます。

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

代案

ブラウザとフル入力機能にアクセスできる Android、iOS、macOS、Linux、Windows などのプラットフォーム(ユニバーサル Windows プラットフォームを含む)向けにアプリを作成する場合は、モバイル アプリケーションおよびデスクトップ アプリケーション用の OAuth 2.0 フローを使用します。(アプリがグラフィカル インターフェースのないコマンドライン ツールであっても、このフローを使用する必要があります)。

Google アカウントを使用してのみユーザーをログインさせ、JWT ID トークンを使用して基本的なユーザー プロフィール情報を取得する場合は、テレビと制限付き入力デバイスでのログインをご覧ください。

Prerequisites

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

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

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

  1. Google API ConsoleのOpen the API Library
  2. If prompted, select a project, or create a new one.
  3. [ライブラリ] ページで、YouTube Data API を探して有効にします。アプリケーションで使用するその他の API を探して、それも有効にします。

承認認証情報を作成する

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

  1. Go to the Credentials page.
  2. [認証情報を作成] > [OAuth クライアント ID] をクリックします。
  3. アプリケーションの種類として [テレビと制限付き入力デバイス] を選択します。
  4. OAuth 2.0 クライアントに名前を付け、[作成] をクリックします。

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

スコープを使用すると、アプリケーションは必要なリソースへのアクセス権のみをリクエストでき、ユーザーはアプリケーションに付与するアクセス権の量を制御できます。したがって、リクエストするスコープの数とユーザーの同意を取得する可能性の間には、反比例の関係がある可能性があります。

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

他の動画を管理する

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

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

インストール済みのアプリやデバイスについては、許可されたスコープのリストをご覧ください。

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

入力機能が制限されたデバイス上でアプリが実行される場合でも、ユーザーは認証フローを完了するために、より多くの入力機能を持つデバイスに対して個別にアクセス権を持っている必要があります。 フローの手順は次のとおりです。

  1. アプリケーションは、アクセス権限をリクエストするスコープを識別するリクエストを Google の承認サーバーに送信します。
  2. サーバーは、デバイスコードやユーザーコードなど、以降のステップで使用するいくつかの情報を返します。
  3. ユーザーが別のデバイスに入力してアプリを承認できる情報を表示します。
  4. アプリケーションが Google の承認サーバーのポーリングを開始し、ユーザーがアプリを認可したかどうか判断します。
  5. ユーザーは、入力機能が豊富なデバイスに切り替えてウェブブラウザを起動し、ステップ 3 に表示されている URL に移動して、ステップ 3 でも表示されるコードを入力します。ユーザーは、アプリケーションにアクセス権を付与(または拒否)できます。
  6. ポーリング リクエストへの次のレスポンスには、アプリがユーザーに代わってリクエストを承認するために必要なトークンが含まれています。(ユーザーがアプリケーションへのアクセスを拒否した場合、レスポンスにはトークンが含まれません)。

次の図に、このプロセスを示します。

ユーザーが、ブラウザを搭載した別のデバイスにログインした

以降のセクションでは、これらの手順について詳しく説明します。デバイスに搭載されている可能性のある機能とランタイム環境には違いがあるため、このドキュメントの例では curl コマンドライン ユーティリティを使用しています。これらの例は、さまざまな言語やランタイムに移植しやすいものである必要があります。

ステップ 1: デバイスとユーザーコードをリクエストする

このステップでは、デバイスは、ユーザーに代わってアプリケーションがアクセスするアクセス スコープとアプリケーションを識別する HTTP POST リクエストを Google の認可サーバー(https://oauth2.googleapis.com/device/code)に送信します。 この URL は、ディスカバリ ドキュメントから device_authorization_endpoint メタデータ値を使用して取得する必要があります。次の HTTP リクエスト パラメータを含めます。

パラメータ
client_id 必須

アプリケーションのクライアント ID。この値は API Console Credentials pageにあります。

scope 必須

アプリケーションがユーザーに代わってアクセスできるリソースを識別するスコープをスペースで区切ったリスト。これらの値は、Google がユーザーに表示する同意画面を通知するものです。インストールされているアプリまたはデバイスについては、許可されたスコープのリストをご覧ください。

スコープを使用すると、アプリケーションは必要なリソースへのアクセスのみをリクエストできます。また、ユーザーはアプリケーションに付与するアクセス権の量を制御できます。したがって、リクエストされたスコープの数とユーザーの同意を取得する可能性の間には反比例があります。

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

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

Google API へのアクセスに使用できるスコープの一覧については、OAuth 2.0 API スコープをご覧ください。

次のスニペットに、サンプル リクエストを示します。

POST /device/code HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=client_id&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly

次の例は、同じリクエストを送信する curl コマンドを示しています。

curl -d "client_id=client_id&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly" \
     https://oauth2.googleapis.com/device/code

ステップ 2: 認証サーバー レスポンスを処理する

承認サーバーは次のいずれかのレスポンスを返します。

成功のレスポンス

リクエストが有効な場合、レスポンスは次のプロパティを含む JSON オブジェクトになります。

プロパティ
device_code 認可を要求するアプリを実行するデバイスを識別するために Google が一意に割り当てる値。ユーザーは、入力機能が豊富な別のデバイスからそのデバイスを承認できます。たとえば、ユーザーがノートパソコンやスマートフォンを使用して、テレビで実行されるアプリを認可することがあります。この場合、テレビは device_code によって識別されます。

このコードにより、アプリを実行しているデバイスは、ユーザーがアクセスを許可または拒否したかどうかを安全に判断できます。

expires_in device_codeuser_code の有効期間(秒)です。その間に、ユーザーが承認フローを完了せず、デバイスがユーザーの判断に関する情報を取得するためにポーリングしない場合は、手順 1 からこのプロセスを再開する必要があります。
interval デバイスがポーリング リクエスト間の待機時間(秒)です。たとえば、値が 5 の場合、デバイスは 5 秒ごとに Google の承認サーバーにポーリング リクエストを送信します。詳しくは、ステップ 3 をご覧ください。
user_code アプリケーションがアクセスをリクエストしているスコープを Google が識別する、大文字と小文字が区別される値。ユーザー インターフェースは、入力機能が豊富な別のデバイスにこの値を入力するようユーザーに指示するものです。Google は、ユーザーにアプリケーションへのアクセスを許可するように求めるときに、この値を使用して正しいスコープのセットを表示します。
verification_url ユーザーが user_code に移動してアプリへのアクセスを許可または拒否するために、別のデバイスで移動する必要がある URL。ユーザー インターフェースにもこの値が表示されます。

次のスニペットに、サンプル レスポンスを示します。

{
  "device_code": "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",
  "user_code": "GQVQ-JKEC",
  "verification_url": "https://www.google.com/device",
  "expires_in": 1800,
  "interval": 5
}

割り当て超過のレスポンス

デバイスのコード リクエストがクライアント ID に関連付けられた割り当てを超えると、次のエラーを含む 403 レスポンスが返されます。

{
  "error_code": "rate_limit_exceeded"
}

その場合は、バックオフ戦略を使用してリクエストの割合を下げてください。

手順 3: ユーザーコードを表示する

ステップ 2 で取得した verification_urluser_code をユーザーに表示します。どちらの値にも US-ASCII 文字セットの任意の印刷可能文字を含めることができます。ユーザーに表示するコンテンツは、別のデバイスで verification_url に移動して user_code を入力するようにユーザーに指示する必要があります。

ユーザー インターフェース(UI)は、以下のルールを考慮して設計してください。

  • user_code
    • user_code は、15 個の「W」サイズの文字を処理できるフィールドに表示される必要があります。つまり、コード WWWWWWWWWWWWWWW を正しく表示できれば UI は有効です。UI で user_code がどのように表示されるかをテストする際に、その文字列値を使用することをおすすめします。
    • user_code では大文字と小文字が区別されるため、大文字と小文字の区別やその他の書式設定文字の挿入など、いかなる変更もしないでください。
  • verification_url
    • verification_url を表示するスペースは、40 文字の URL 文字列を処理するのに十分な幅が必要です。
    • verification_url は、オプションで表示スキームを削除する場合を除き、変更しないでください。表示上の理由で URL からスキーム(https:// など)を削除する場合は、アプリで httphttps の両方のバリアントを処理できるようにしてください。

ステップ 4: Google の認可サーバーをポーリングする

ユーザーは別のデバイスを使用して verification_url に移動し、アクセスを許可(または拒否)するため、ユーザーがアクセス リクエストに応答したときにリクエスト元のデバイスには自動的に通知されません。そのため、リクエスト元のデバイスは Google の承認サーバーにポーリングして、ユーザーがリクエストに応答したかどうかを判断する必要があります。

ユーザーがアクセス リクエストに応答したことを示すレスポンスを受け取るか、 ステップ 2 で取得した device_codeuser_code が期限切れになるまで、リクエスト元のデバイスはポーリング リクエストの送信を続行する必要があります。ステップ 2 で返された interval には、リクエスト間の待機時間を秒単位で指定します。

ポーリングするエンドポイントの URL は https://oauth2.googleapis.com/token です。ポーリング リクエストには次のパラメータが含まれます。

パラメータ
client_id アプリケーションのクライアント ID。この値は API Console Credentials pageにあります。
client_secret 指定された client_id のクライアント シークレット。この値は API Console Credentials pageにあります。
device_code ステップ 2 で認可サーバーから返された device_code を返します。
grant_type urn:ietf:params:oauth:grant-type:device_code に設定します。

次のスニペットに、サンプル リクエストを示します。

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

client_id=client_id&
client_secret=client_secret&
device_code=device_code&
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code

次の例は、同じリクエストを送信する curl コマンドを示しています。

curl -d "client_id=client_id&client_secret=client_secret& \
         device_code=device_code& \
         grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code" \
         -H "Content-Type: application/x-www-form-urlencoded" \
         https://oauth2.googleapis.com/token

ステップ 5: お客様がアクセス リクエストに応答する

次の画像は、ステップ 3verification_url に移動するとユーザーに表示されるページを示しています。

コードを入力してデバイスを接続する

user_code にログインし、まだログインしていない場合、次のような同意画面が表示されます。

デバイス クライアント用の同意画面の例

ステップ 6: ポーリング リクエストに対するレスポンスを処理する

Google の認可サーバーは、次のいずれかのポーリング リクエストに対して、次のいずれかのレスポンスを返します。

アクセスを許可しました

ユーザーが同意画面で [Allow] をクリックしてデバイスへのアクセス権を付与した場合、レスポンスにはアクセス トークンと更新トークンが含まれます。トークンを使用すると、デバイスがユーザーに代わって Google API にアクセスできるようになります。(レスポンスの scope プロパティによって、デバイスがアクセスできる API が決まります)。

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

フィールド
access_token Google API リクエストを承認するためにアプリケーションから送信されたトークン。
expires_in アクセス トークンの残りの有効期間(秒)。
refresh_token 新しいアクセス トークンの取得に使用できるトークン。更新トークンは、ユーザーがアクセス権を取り消すまで有効です。 なお、デバイスの場合、更新トークンは常に返されます。
scope access_token によって付与されるアクセス スコープ。スペース区切りの大文字と小文字が区別される文字列のリストとして表されます。
token_type 返されるトークンのタイプ。現時点では、このフィールドの値は常に Bearer に設定されます。

次のスニペットに、サンプル レスポンスを示します。

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
  "token_type": "Bearer",
  "refresh_token": "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

アクセス トークンの有効期間は限られています。アプリケーションで長期間にわたって API にアクセスする必要がある場合は、更新トークンを使用して新しいアクセス トークンを取得できます。アプリケーションでこのタイプのアクセスが必要な場合は、後で使用できるように更新トークンを保存する必要があります。

アクセスが拒否されました

ユーザーがデバイスへのアクセスを拒否した場合、サーバー レスポンスには 403 HTTP レスポンス ステータス コード(Forbidden)が含まれます。レスポンスには、次のエラーが含まれます。

{
  "error": "access_denied",
  "error_description": "Forbidden"
}

承認待ち

ユーザーがまだ承認フローを完了していない場合、サーバーは 428 HTTP レスポンス ステータス コード(Precondition Required)を返します。レスポンスには、次のエラーが含まれます。

{
  "error": "authorization_pending",
  "error_description": "Precondition Required"
}

アンケートの頻度が多すぎる

デバイスがポーリング リクエストを頻繁に送信すると、サーバーは 403 HTTP レスポンス ステータス コード(Forbidden)を返します。レスポンスには、次のエラーが含まれます。

{
  "error": "slow_down",
  "error_description": "Forbidden"
}

その他のエラー

また、ポーリング リクエストに必須パラメータがない場合や、パラメータ値が正しくない場合は、認可サーバーからエラーが返されます。通常、これらのリクエストには 400Bad Request)または 401Unauthorized)の HTTP レスポンス ステータス コードが含まれます。発生するエラーには次のようなものがあります。

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

OAuth クライアントが見つかりませんでした。このエラーは、たとえば client_id パラメータ値が無効な場合に発生します。

OAuth クライアントの種類が正しくありません。クライアント ID のアプリケーション タイプTV と制限付き入力デバイスに設定されていることを確認します。

invalid_grant 400 code パラメータ値が無効です。すでに申し立てが行われているか、解析できません。
unsupported_grant_type 400 grant_type パラメータ値が無効です。
org_internal 403 リクエストの OAuth クライアント ID は、特定の Google Cloud 組織の Google アカウントへのアクセスを制限するプロジェクトの一部です。OAuth アプリケーションのユーザータイプの構成を確認します。

Google API の呼び出し

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

YouTube Data API では、レコード レーベルや映画制作会社など、複数の YouTube チャンネルを所有および管理する YouTube コンテンツ所有者のみがサービス アカウントをサポートしています。

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

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から取得したクライアント シークレット。
grant_type OAuth 2.0 仕様で定義されているように、このフィールドの値は refresh_token に設定する必要があります。
refresh_token 認証コード交換から返された更新トークン。

次のスニペットに、サンプル リクエストを示します。

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

client_id=your_client_id&
client_secret=your_client_secret&
refresh_token=refresh_token&
grant_type=refresh_token

アプリケーションに付与されたアクセス権をユーザーが取り消していない限り、トークン サーバーは新しいアクセス トークンを含む JSON オブジェクトを返します。次のスニペットは、レスポンスの例を示しています。

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

発行される更新トークンの数には上限があります。1 つのクライアントとユーザーの組み合わせごとに 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 がエラーコードとともに返されます。

許可されたスコープ

デバイスの OAuth 2.0 フローは、次のスコープでのみサポートされます。

OpenID ConnectGoogle ログイン

  • email
  • openid
  • profile

Drive API

  • https://www.googleapis.com/auth/drive.appdata
  • https://www.googleapis.com/auth/drive.file

YouTube API

  • https://www.googleapis.com/auth/youtube
  • https://www.googleapis.com/auth/youtube.readonly