このドキュメントでは、テレビ、ゲーム機、プリンタなどのデバイスで実行されているアプリケーションから Google API にアクセスするために OAuth 2.0 認証を実装する方法について説明します。具体的には、このフローは、ブラウザにアクセスできないデバイス、または入力機能が制限されているデバイス向けに設計されています。
OAuth 2.0 では、ユーザー名やパスワードなどの情報を秘密にしたまま、ユーザーが特定のデータをアプリケーションと共有できます。たとえば、テレビ アプリケーションは OAuth 2.0 を使用して、Google ドライブに保存されているファイルを選択する権限を取得できます。
このフローを使用するアプリは個々のデバイスに配布されるため、アプリがシークレットを保持できないことが前提となります。ユーザーがアプリを使用しているとき、またはアプリがバックグラウンドで実行されているときに、Google API にアクセスできます。
代替手段
ブラウザと完全な入力機能にアクセスできる Android、iOS、macOS、Linux、Windows(ユニバーサル Windows プラットフォームを含む)などのプラットフォーム用のアプリを作成する場合は、モバイル アプリとデスクトップ アプリ用の OAuth 2.0 フローを使用します。(アプリがグラフィカル インターフェースのないコマンドライン ツールの場合でも、このフローを使用する必要があります)。
Google アカウントでユーザーにログインさせ、JWT ID トークンを使用して基本的なユーザー プロフィール情報を取得するだけの場合は、テレビと入力制限のあるデバイスでのログインをご覧ください。
前提条件
プロジェクトでAPI を有効にする
Google API を呼び出すアプリケーションは、 API Consoleでそれらの API を有効にする必要があります。
プロジェクトで API を有効にするには:
- Google API ConsoleのOpen the API Library 。
- If prompted, select a project, or create a new one.
- API Library には、利用可能なすべての API がプロダクト ファミリーと人気度に応じて分類されて表示されます。有効にする API がリストで見当たらない場合は、検索して見つけるか、その API が属するプロダクト ファミリーで [すべて表示] をクリックします。
- 有効にする API を選択し、[有効にする] ボタンをクリックします。
- If prompted, enable billing.
- If prompted, read and accept the API's Terms of Service.
承認認証情報を作成する
OAuth 2.0 を使用して Google API にアクセスするアプリケーションは、Google の OAuth 2.0 サーバーに対して自身の身元を示す認証情報を持つ必要があります。次の手順では、プロジェクトの認証情報を作成する方法について説明します。アプリケーションは、この認証情報を使用して、そのプロジェクトで有効にした API にアクセスできます。
- Go to the Credentials page.
- [Create Client] をクリックします。
- [テレビと入力が限られたデバイス] アプリケーション タイプを選択します。
- OAuth 2.0 クライアントに名前を付けて、[作成] をクリックします。
アクセス スコープを特定する
スコープを指定すると、アプリケーションからのアクセス要求は必要なリソースのみに限定されるようになり、ユーザーはアプリケーションに付与するアクセスレベルを制御できます。したがって、リクエストされるスコープの数とユーザーの同意を得られる可能性の間には逆相関がある可能性があります。
OAuth 2.0 認証の実装を開始する前に、アプリがアクセス権限を必要とするスコープを設定しておくことをおすすめします。
インストールされているアプリまたはデバイスの許可されているスコープのリストをご覧ください。
OAuth 2.0 アクセス トークンを取得する
アプリが入力機能が制限されたデバイスで実行される場合でも、ユーザーはこの認証フローを完了するために、入力機能が豊富なデバイスに別途アクセスする必要があります。このフローの手順は次のとおりです。
- アプリケーションは、アクセス権限をリクエストするスコープを識別するリクエストを Google の認可サーバーに送信します。
- サーバーは、デバイスコードやユーザーコードなど、後続のステップで使用される複数の情報を返します。
- ユーザーが別のデバイスで入力してアプリを承認できる情報を表示します。
- アプリは Google の認証サーバーへのポーリングを開始し、ユーザーがアプリを承認したかどうかを判断します。
- ユーザーが入力機能が豊富なデバイスに切り替え、ウェブブラウザを起動して、ステップ 3 で表示された URL に移動し、ステップ 3 で表示されたコードを入力します。ユーザーはアプリケーションへのアクセス権を付与(または拒否)できます。
- ポーリング リクエストに対する次のレスポンスには、ユーザーに代わってリクエストを承認するためにアプリが必要とするトークンが含まれています。(ユーザーがアプリへのアクセスを拒否した場合、レスポンスにトークンは含まれません)。
次の図は、このプロセスを示しています。

以降のセクションで、これらの手順について詳しく説明します。デバイスが備える機能とランタイム環境は多岐にわたるため、このドキュメントで示す例では curl
コマンドライン ユーティリティを使用します。これらの例は、さまざまな言語やランタイムに簡単に移植できる必要があります。
ステップ 1: デバイスコードとユーザーコードをリクエストする
このステップでは、デバイスが https://oauth2.googleapis.com/device/code
の Google 認証サーバーに HTTP POST リクエストを送信します。このリクエストでは、アプリケーションと、ユーザーに代わってアプリケーションがアクセスを希望するアクセス スコープが識別されます。この URL は、device_authorization_endpoint
メタデータ値を使用して、ディスカバリ ドキュメントから取得する必要があります。次の HTTP リクエスト パラメータを含めます。
パラメータ | |
---|---|
client_id |
必須
アプリケーションのクライアント ID。この値は、 にあります。 |
scope |
必須
アプリケーションがユーザーの代わりにアクセスできるリソースを識別するスコープのスペース区切りリスト。これらの値は、Google がユーザーに表示する同意画面に反映されます。インストールされているアプリまたはデバイスの許可されているスコープのリストをご覧ください。 スコープを指定すると、アプリケーションからのアクセス要求は必要なリソースのみに限定されるようになり、ユーザーはアプリケーションに付与するアクセスレベルを制御できます。したがって、リクエストされるスコープの数とユーザーの同意が得られる可能性の間には逆相関があります。 |
例
次のスニペットは、リクエストの例を示しています。
POST /device/code HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=client_id&scope=email%20profile
この例は、同じリクエストを送信する curl
コマンドを示しています。
curl -d "client_id=client_id&scope=email%20profile" \ https://oauth2.googleapis.com/device/code
ステップ 2: 認可サーバーのレスポンスを処理する
認可サーバーは、次のいずれかのレスポンスを返します。
成功のレスポンス
リクエストが有効な場合、レスポンスは次のプロパティを含む JSON オブジェクトになります。
プロパティ | |
---|---|
device_code |
Google が一意に割り当てた値。認証をリクエストするアプリを実行しているデバイスを識別します。ユーザーは、より豊富な入力機能を備えた別のデバイスからそのデバイスを承認します。たとえば、ユーザーはノートパソコンやスマートフォンを使用して、テレビで実行されているアプリを承認できます。この場合、device_code はテレビを識別します。このコードにより、アプリを実行しているデバイスは、ユーザーがアクセスを許可したか拒否したかを安全に判断できます。 |
expires_in |
device_code と user_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_url
と user_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://
など)を削除する予定がある場合は、アプリがhttp
とhttps
の両方のバリエーションを処理できることを確認してください。
ステップ 4: Google の認可サーバーをポーリングする
ユーザーは別のデバイスを使用して verification_url
に移動し、アクセスを許可(または拒否)するため、ユーザーがアクセス リクエストに応答しても、リクエスト元のデバイスに自動的に通知されることはありません。そのため、リクエスト元のデバイスは、ユーザーがリクエストに応答したタイミングを判断するために、Google の認証サーバーをポーリングする必要があります。
リクエスト元のデバイスは、ユーザーがアクセス リクエストに応答したことを示すレスポンスを受け取るまで、または
ステップ 2 で取得した device_code
と user_code
の有効期限が切れるまで、ポーリング リクエストを送信し続ける必要があります。ステップ 2 で返された interval
は、リクエスト間の待機時間(秒単位)を指定します。
ポーリングするエンドポイントの URL は https://oauth2.googleapis.com/token
です。ポーリング リクエストには次のパラメータが含まれます。
パラメータ | |
---|---|
client_id |
アプリケーションのクライアント ID。この値は、 にあります。 |
client_secret |
指定された client_id のクライアント シークレット。この値は、
にあります。 |
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: ユーザーがアクセス リクエストに応答する
次の画像は、ステップ 3 で表示した verification_url
に移動したときにユーザーに表示されるページに似たページを示しています。

user_code
を入力し、まだログインしていない場合は Google にログインすると、以下のような同意画面が表示されます。

ステップ 6: ポーリング リクエストへのレスポンスを処理する
Google の認可サーバーは、各ポーリング リクエストに対して次のいずれかのレスポンスを返します。
アクセス権が付与されました
ユーザーがデバイスへのアクセスを許可した場合(同意画面で Allow
をクリックした場合)、レスポンスにはアクセス トークンと更新トークンが含まれます。トークンを使用すると、デバイスはユーザーに代わって Google API にアクセスできます。(レスポンスの scope
プロパティは、デバイスがアクセスできる API を決定します)。
この場合、API レスポンスには次のフィールドが含まれます。
フィールド | |
---|---|
access_token |
Google API リクエストを承認するためにアプリケーションが送信するトークン。 |
expires_in |
アクセス トークンの残りの有効期間(秒単位)。 |
refresh_token |
新しいアクセス トークンを取得するために使用できるトークン。更新トークンは、ユーザーがアクセスを取り消すか、更新トークンの有効期限が切れるまで有効です。デバイスに対しては常にリフレッシュ トークンが返されることに注意してください。 |
refresh_token_expires_in |
更新トークンの残りの有効期間(秒単位)。この値は、ユーザーが時間ベースのアクセスを許可した場合にのみ設定されます。 |
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" }
その他のエラー
認可サーバーは、ポーリング リクエストに必要なパラメータが欠落している場合や、パラメータ値が正しくない場合にもエラーを返します。通常、これらのリクエストには 400
(Bad Request
)または 401
(Unauthorized
)の HTTP レスポンス ステータス コードが含まれます。エラーには次のようなものがあります。
エラー | HTTP ステータス コード | 説明 |
---|---|---|
admin_policy_enforced |
400 |
Google アカウントの Google Workspace 管理者のポリシーにより、リクエストされた 1 つ以上のスコープを承認できません。管理者が OAuth クライアント ID に明示的にアクセス権を付与するまで、スコープへのアクセスを制限する方法について詳しくは、Google Workspace 管理者向けヘルプ記事の Google Workspace のデータにアクセスできるサードパーティ製アプリと内部アプリを制御するをご覧ください。 |
invalid_client |
401 |
OAuth クライアントが見つかりませんでした。たとえば、 OAuth クライアント タイプが正しくありません。クライアント ID のアプリケーション タイプが [テレビと入力制限付きデバイス] に設定されていることを確認します。 |
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 への呼び出しを設定できます(たとえば、Drive Files API を呼び出す場合など)。
OAuth 2.0 Playground では、すべての Google API を試して、そのスコープを確認できます。
HTTP GET の例
Authorization: Bearer
HTTP ヘッダーを使用して
drive.files
エンドポイント(ドライブ ファイル API)を呼び出すと、次のようになります。独自のアクセス トークンを指定する必要があります。
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
以下は、access_token
クエリ文字列パラメータを使用して、認証済みユーザーに対して同じ API を呼び出す例です。
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
curl
の例
これらのコマンドは、curl
コマンドライン アプリケーションでテストできます。HTTP ヘッダー オプション(推奨)を使用する例を次に示します。
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
または、クエリ文字列パラメータ オプションを使用します。
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
アクセス トークンをリフレッシュする
アクセス トークンは定期的に期限が切れ、関連する 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 https://www.googleapis.com/auth/calendar.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
が返されます。
許可されたスコープ
デバイスの OAuth 2.0 フローは、次のスコープでのみサポートされています。
OpenID Connect、Google ログイン
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
時間に基づくアクセス
時間ベースのアクセスでは、ユーザーはアクションを完了するために、アプリが期間限定でデータにアクセスすることを許可できます。時間ベースのアクセスは、同意フロー中に一部の Google サービスで利用できます。ユーザーは、限られた期間のみアクセスを許可するオプションを選択できます。たとえば、 Data Portability API を使用すると、データを 1 回だけ転送できます。
ユーザーがアプリに時間ベースのアクセス権を付与すると、更新トークンは指定された期間の経過後に期限切れになります。特定の状況下では、更新トークンが早期に無効になることがあります。詳しくは、こちらのケースをご覧ください。このような場合、認可コード交換レスポンスで返される refresh_token_expires_in
フィールドは、更新トークンの有効期限が切れるまでの残り時間を表します。
クロスアカウント保護機能の実装
ユーザーのアカウントを保護するために行うべき追加の手順として、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
クロスアカウント保護の実装方法と利用可能なイベントの完全なリストについては、 クロスアカウント保護でユーザー アカウントを保護する をご覧ください。