このドキュメントでは、TV、ゲーム機、プ��ン��な���の��バイス������行されているアプリケーションから Google API にアクセスするための OAuth 2.0 認証を実装する方法について説明します。具体的には、このフローは、ブラウザにアクセスできないデバイスまたは入力機能が制限されているデバイス向けに設計されています。
OAuth 2.0 を使用すると、ユーザー名やパスワードなどの情報を非公開にしたまま、特定のデータをアプリケーションと共有することができます。たとえば、TV アプリケーションは OAuth 2.0 を使用して、Google ドライブに保存されたファイルを選択する権限を取得できます。
このフローを使用するアプリケーションは個々のデバイスに分散されるため、アプリはシークレットを保持できないとみなされます。ユーザーがアプリを使用しているときやアプリがバックグラウンドで実行されているときに、Google API にアクセスできます。
代替手段
Android、iOS、macOS、Linux、Windows などのプラットフォーム(Universal Windows Platform を含む)向けに、ブラウザにアクセスしてすべての入力機能を使用できるアプリを作成する場合は、モバイルおよびデスクトップ アプリケーション用の 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.
- [認証情報を作成] > [OAuth クライアント ID] をクリックします。
- アプリケーション タイプとして [テレビと入力制限のあるデバイス] を選択します。
- OAuth 2.0 クライアントに名前を付け、[作成] をクリックします。
アクセス スコープを特定する
スコープを使用すると、アプリケーションが必要なリソースへのアクセス権のみをリクエストできます。また、ユーザーはアプリケーションに付与するアクセス権の量を制御できます。したがって、リクエストするスコープの数とユーザーの同意を得る可能性の間に逆相関関係がある場合があります。
OAuth 2.0 認証の実装を開始する前に、アプリがアクセス権限を必要とするスコープを特定することをおすすめします。
インストール済みのアプリまたはデバイスについては、許可されるスコープのリストをご覧ください。
OAuth 2.0 アクセス トークンの取得
アプリは入力機能が制限されたデバイス上で実行されていても、この承認フローを完了するには、ユーザーはより豊富な入力機能を備えたデバイスに別途アクセスする必要があります。このフローには次の手順が含まれます。
- アプリケーションがアクセス権限をリクエストするスコープを Google の承認サーバーに送信する。
- サーバーは、デバイスコードやユーザーコードなど、以降のステップで使用するいくつかの情報を返します。
- ユーザーがアプリを承認するために、ユーザーが別のデバイスに入力できる情報を表示します。
- アプリケーションが Google の承認サーバーへのポーリングを開始し、ユーザーがアプリを承認したかどうかを判断します。
- 入力機能が充実したデバイスに切り替えて、ウェブブラウザを起動し、ステップ 3 で表示した URL に移動してコードを入力します。このコードはステップ 3 でも表示されます。ユーザーはアプリケーションへのアクセスを許可(または拒否)できます。
- ポーリング リクエストに対する次のレスポンスには、アプリがユーザーに代わってリクエストを承認するために必要なトークンが含まれています。(ユーザーがアプリケーションへのアクセスを拒否した場合、レスポンスにトークンは含まれません)。
次の図に、このプロセスを示します。
以降のセクションでは、これらのステップについて詳しく説明します。デバイスの機能とランタイム環境の範囲を考慮して、このドキュメントの例では curl
コマンドライン ユーティリティを使用しています。これらの例は、さまざまな言語やランタイムに簡単に移植できるものでなければなりません。
ステップ 1: デバイスとユーザーコードをリクエストする
このステップでは、デバイスから Google の承認サーバー(https://oauth2.googleapis.com/device/code
)に HTTP POST リクエストを送信します。このリクエストは、ユーザーの代わりにアプリがアクセスするアクセス スコープと、アプリを識別します。
この URL は、device_authorization_endpoint
メタデータ値を使用してディスカバリ ドキュメントから取得する必要があります。次の HTTP リクエスト パラメータを含めます。
パラメータ | |
---|---|
client_id |
必須 アプリケーションのクライアント ID。この値は API Console Credentials pageで確認できます。 |
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 オブジェクトになります。
Properties | |
---|---|
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。この値は 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: ユーザーがアクセス権のリクエストに応答する
次の図は、ステップ 3 で表示された verification_url
に移動したときにユーザーに表示されるページと似たページです。
user_code
を入力し、まだログインしていない場合は、Google にログインすると、次のような同意画面が表示されます。
ステップ 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" }
その他のエラー
ポーリング リクエストに必須パラメータがない場合や、パラメータ値が正しくない場合も、認可サーバーはエラーを返します。通常、これらのリクエストには、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
エンドポイント(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 リクエストでは無効な認証情報になります。トークンに関連付けられたスコープへのオフライン アクセスをリクエストした場合、ユーザーに権限を求めることなくアクセス トークンを更新できます(ユーザーが存在しない場合を含む)。
アクセス トークンを更新するには、アプリケーションから Google の承認サーバー(https://oauth2.googleapis.com/token
)に、次のパラメータを含む HTTPS POST
リクエストを送信します。
フィールド | |
---|---|
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 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