このドキュメントでは、OAuth 2.0 認証を実装して JavaScript ウェブ アプリケーションから Google API にアクセスする方法について説明します。OAuth 2.0 を使用すると、ユーザー名やパスワードなどの情報を秘密にしたまま、ユーザーが特定のデータをアプリケーションと共有できます。 たとえば、アプリケーションは OAuth 2.0 を使用して、Google ドライブにファイルを保存する権限をユーザーから取得できます。
この OAuth 2.0 フローは暗黙的付与フローと呼ばれます。ユーザーがアプリを開いている間だけ API にアクセスするアプリ向けに設計されています。これらのアプリケーションは機密情報を保存できません。
このフローでは、アプリが Google URL を開きます。この URL でクエリ パラメータを使用して、アプリとアプリに必要な API アクセスのタイプを識別します。URL は、現在のブラウザ ウィンドウまたはポップアップで開くことができます。ユーザーは Google で認証を行い、リクエストされた権限を付与できます。Google はユーザーをアプリにリダイレクトします。リダイレクトにはアクセス トークンが含まれます。アプリはこのアクセス トークンを確認し、このトークンを使用して API リクエストを行います。
Google API クライアント ライブラリと Google Identity Services
JavaScript 用の Google API クライアント ライブラリを使用して Google への承認済みの呼び出しを行う場合は、 Google Identity Services JavaScript ライブラリを使用して OAuth 2.0 フローを処理する必要があります。Google Identity Services のトークンモデルをご覧ください。このトークンは、OAuth 2.0 の暗黙的な付与フローに基づいています。
Prerequisites
プロジェクトで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] をクリックします。
- アプリケーションの種類として [ウェブ アプリケーション] を選択します。
- フォームに入力します。JavaScript を使用して承認済みの Google API リクエストを送信するアプリケーションは、承認済みの JavaScript 生成元を指定する必要があります。オリジンは、アプリケーションが OAuth 2.0 サーバーにリクエストを送信できるドメインを識別します。これらのオリジンは、Google の検証ルールに準拠している必要があります。
アクセス スコープを特定する
スコープを使用すると、アプリケーションは必要なリソースへのアクセスのみをリクエストできます。また、ユーザーはアプリケーションに付与するアクセス権の量を制御することもできます。そのため、リクエストするスコープの数とユーザーの同意を得る可能性の間には逆の関係がある場合があります。
OAuth 2.0 認証の実装を開始する前に、アプリがアクセス権限を必要とするスコープを特定することをおすすめします。
OAuth 2.0 API スコープのドキュメントには、Google API へのアクセスに使用できるスコープの一覧が記載されています。
OAuth 2.0 アクセス トークンの取得
以下の手順では、アプリケーションが Google の OAuth 2.0 サーバーとやり取りし、ユーザーの代わりに API リクエストを実行することについてユーザーの同意を得ます。ユーザーの承認が必要な Google API リクエストをアプリケーションで実行するには、この同意が必要です。
ステップ 1: Google の OAuth 2.0 サーバーにリダイレクトする
ユーザーのデータにアクセスする権限をリクエストするには、ユーザーを Google の OAuth 2.0 サーバーにリダイレクトします。
OAuth 2.0 エンドポイント
Google の OAuth 2.0 エンドポイント(https://accounts.google.com/o/oauth2/v2/auth
)からアクセスをリクエストするための URL を生成します。このエンドポイントには HTTPS 経由でアクセスできます。プレーン HTTP 接続は拒否されます。
Google 認証サーバーは、ウェブサーバー アプリケーション用に次のクエリ文字列パラメータをサポートしています。
パラメータ | |||||||
---|---|---|---|---|---|---|---|
client_id |
必須
アプリケーションのクライアント ID。この値は API Console Credentials pageで確認できます。 |
||||||
redirect_uri |
必須
ユーザーが認可フローを完了した後に、API サーバーがユーザーをリダイレクトする場所を決定します。この値は、OAuth 2.0 クライアントで承認されたリダイレクト URI のいずれかと完全に一致する必要があります。これは、クライアントの API Console
Credentials pageに構成したものです。この値が、指定された
|
||||||
response_type |
必須
JavaScript アプリケーションでは、パラメータの値を |
||||||
scope |
必須
ユーザーの代わりにアプリケーションがアクセスできるリソースを指定するスコープのスペース区切りリスト。これらの値は、Google がユーザーに表示する同意画面に反映されます。 スコープを使用すると、アプリケーションは必要なリソースへのアクセスのみをリクエストできます。また、ユーザーはアプリケーションに付与するアクセス権の量を制御することもできます。したがって、リクエストされるスコープの数とユーザーの同意を得る可能性には反比例します。 アプリケーションは、可能な限り、コンテキストに沿って認可スコープへのアクセスをリクエストすることをおすすめします。段階的な承認を介して、状況に応じてユーザーデータへのアクセスをリクエストすると、アプリケーションがアクセスを必要とする理由をユーザーがより簡単に理解できるようになります。 |
||||||
state |
推奨
アプリケーションが認可リクエストと認可サーバーのレスポンスの間で状態を維持するために使用する任意の文字列値を指定します。ユーザーがアプリケーションのアクセス リクエストに同意または拒否すると、サーバーは このパラメータは、アプリ内の適切なリソースにユーザーを誘導する、ノンスを送信する、クロスサイト リクエスト フォージェリを抑制するなど、さまざまな目的で使用できます。 |
||||||
include_granted_scopes |
省略可
アプリケーションは、増分承認を使用して、状況に応じて追加のスコープへのアクセスをリクエストできます。このパラメータの値を |
||||||
enable_granular_consent |
省略可
デフォルトは |
||||||
login_hint |
省略可
認証しようとしているユーザーをアプリケーションが認識している場合は、このパラメータを使用して、Google 認証サーバーにヒントを提供できます。サーバーはこのヒントを使用して、ログイン フォームのメール フィールドに事前入力するか、適切なマルチログイン セッションを選択することで、ログインフローを簡素化します。 パラメータ値を、ユーザーの Google ID に相当するメールアドレスまたは |
||||||
prompt |
省略可
ユーザーに表示するためのプロンプトのスペース区切りリスト(大文字と小文字を区別)。このパラメータを指定しない場合、プロジェクトが初めてアクセスをリクエストしたときにのみ、ユーザーにメッセージが表示されます。詳しくは、 再同意を求めるをご覧ください。 表示される値は次のとおりです。
|
Google の承認サーバーへのリダイレクトの例
次に、URL の例を示します。読みやすくするため、改行とスペースを入れています。
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly& include_granted_scopes=true& response_type=token& state=state_parameter_passthrough_value& redirect_uri=https%3A//oauth2.example.com/code& client_id=client_id
リクエスト URL を作成したら、ユーザーをその URL にリダイレクトします。
JavaScript サンプルコード
次の JavaScript スニペットは、JavaScript 用 Google API クライアント ライブラリを使用せずに、JavaScript で認可フローを開始する方法を示しています。この OAuth 2.0 エンドポイントはクロスオリジン リソース シェアリング(CORS)をサポートしていないため、スニペットはこのエンドポイントへのリクエストを開くフォームを作成します。
/* * Create form to request access token from Google's OAuth 2.0 server. */ function oauthSignIn() { // Google's OAuth 2.0 endpoint for requesting an access token var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth'; // Create <form> element to submit parameters to OAuth 2.0 endpoint. var form = document.createElement('form'); form.setAttribute('method', 'GET'); // Send as a GET request. form.setAttribute('action', oauth2Endpoint); // Parameters to pass to OAuth 2.0 endpoint. var params = {'client_id': 'YOUR_CLIENT_ID', 'redirect_uri': 'YOUR_REDIRECT_URI', 'response_type': 'token', 'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly', 'include_granted_scopes': 'true', 'state': 'pass-through value'}; // Add form parameters as hidden input values. for (var p in params) { var input = document.createElement('input'); input.setAttribute('type', 'hidden'); input.setAttribute('name', p); input.setAttribute('value', params[p]); form.appendChild(input); } // Add form to page and submit it to open the OAuth 2.0 endpoint. document.body.appendChild(form); form.submit(); }
ステップ 2: 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 ポリシーで許可されていない埋め込みのユーザー エージェント内に表示されています。
Android
Android デベロッパーが android.webkit.WebView
で承認リクエストを開く際に、このエラー メッセージが表示されることがあります。デベロッパーは、代わりに Android 用 Google ログインや OpenID Foundation の AppAuth for Android などの Android ライブラリを使用する必要があります。
Android アプリが埋め込みのユーザー エージェントで一般的なウェブリンクを開き、ユーザーがサイトから Google の OAuth 2.0 認可エンドポイントに移動すると、ウェブ デベロッパーがこのエラーが発生することがあります。デベロッパーは、オペレーティング システムのデフォルトのリンクハンドラで一般的なリンクを開くことを許可する必要があります。これには、Android アプリリンク ハンドラとデフォルトのブラウザアプリの両方が含まれます。Android カスタムタブ ライブラリもサポートされているオプションです。
iOS
iOS または macOS のデベロッパーは、WKWebView
で認証リクエストを開く際にこのエラーが発生することがあります。デベロッパーは、代わりに iOS 用の Google ログインや OpenID Foundation の AppAuth for iOS などの iOS ライブラリを使用する必要があります。
iOS または macOS のアプリが埋め込みユーザー エージェントで一般的なウェブリンクを開き、ユーザーがサイトから Google の OAuth 2.0 認可エンドポイントに移動すると、ウェブ デベロッパーがこのエラーが発生することがあります。デベロッパーは、オペレーティング システムのデフォルトのリンクハンドラで一般的なリンクを開くことを許可する必要があります。これには、ユニバーサル リンク ハンドラとデフォルトのブラウザアプリの両方が含まれます。SFSafariViewController
ライブラリもサポートされているオプションです。
org_internal
リクエスト内の OAuth クライアント ID は、特定の Google Cloud 組織内の Google アカウントへのアクセスを制限するプロジェクトの一部です。この構成オプションの詳細については、OAuth 同意画面の設定に関するヘルプ記事のユーザータイプのセクションをご覧ください。
invalid_client
リクエストの送信元であるオリジンはこのクライアントに対して承認されていません。origin_mismatch
をご覧ください。
invalid_grant
増分承認を使用している場合、トークンが期限切れか、無効化されている可能性があります。 ユーザーを再度認証し、新しいトークンの取得に関するユーザーの同意を求めます。このエラーが引き続き表示される場合は、アプリケーションが正しく構成されていること、リクエストで正しいトークンとパラメータを使用していることを確認してください。それ以外の場合は、ユーザー アカウントが削除または無効化されている可能性があります。
origin_mismatch
認可リクエストを発行する JavaScript のスキーム、ドメイン、ポートが、OAuth クライアント ID に登録された承認済みの JavaScript 生成元 URI と一致しない場合があります。 Credentials pageで承認済みの JavaScript 生成元 Google API Consoleを確認します。
redirect_uri_mismatch
認可リクエストで渡された redirect_uri
が、OAuth クライアント ID の承認済みのリダイレクト URI と一致しません。 Google API Console Credentials pageで承認済みのリダイレクト URI を確認します。
認可リクエストを発行する JavaScript のスキーム、ドメイン、ポートが、OAuth クライアント ID に登録された承認済みの JavaScript 生成元 URI と一致しない場合があります。 Google API Console Credentials pageで承認済みの JavaScript 生成元を確認します。
redirect_uri
パラメータは、非推奨となり、サポートされなくなった OAuth 帯域外(OOB)フローを参照している可能性があります。統合を更新するには、移行ガイドをご覧ください。
invalid_request
リクエストした内容に問題がありました。これにはいくつかの理由が考えられます。
- リクエストの形式が正しくありません
- リクエストに必須パラメータがありません
- リクエストで、Google がサポートしていない認証方法が使用されています。OAuth 統合で推奨の統合方法が使用されていることを確認する
ステップ 3: OAuth 2.0 サーバーのレスポンスを処理する
OAuth 2.0 エンドポイント
OAuth 2.0 サーバーが、アクセス トークン リクエストで指定された redirect_uri
にレスポンスを送信します。
ユーザーがリクエストを承認すると、レスポンスにアクセス トークンが含まれます。ユーザーがリクエストを承認しないと、レスポンスにエラー メッセージが格納されます。アクセス トークンまたはエラー メッセージは、次に示すように、リダイレクト URI のハッシュ フラグメントで返されます。
アクセス トークンのレスポンス:
https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600
access_token
パラメータに加えて、フラグメント文字列には、常にBearer
に設定されるtoken_type
パラメータと、トークンの存続期間を秒単位で指定するexpires_in
パラメータも含まれます。アクセス トークン リクエストでstate
パラメータが指定されている場合は、その値もレスポンスに含まれます。- エラー レスポンス:
https://oauth2.example.com/callback#error=access_denied
OAuth 2.0 サーバーの応答の例
次のサンプル URL をクリックすると、このフローをテストできます。この URL は、Google ドライブのファイルのメタデータを表示するための読み取り専用アクセス権をリクエストします。
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly& include_granted_scopes=true& response_type=token& state=state_parameter_passthrough_value& redirect_uri=https%3A//oauth2.example.com/code& client_id=client_id
OAuth 2.0 フローが完了すると、http://localhost/oauth2callback
にリダイレクトされます。この URL でローカルマシンがファイルを提供しない限り、404 NOT FOUND
エラーが発生します。次のステップでは、ユーザーがアプリケーションにリダイレクトされたときに URI で返される情報の詳細を説明します。
Google API の呼び出し
OAuth 2.0 エンドポイント
アプリケーションがアクセス トークンを取得した後、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
JavaScript サンプルコード
以下のコード スニペットは、CORS(クロスオリジン リソース シェアリング)を使用して Google API にリクエストを送信する方法を示しています。この例では、JavaScript 用の Google API クライアント ライブラリは使用しません。ただし、クライアント ライブラリを使用していない場合でも、該当するライブラリのドキュメントにある CORS サポートガイドが、これらのリクエストについての理解を深めるのに役立ちます。
このコード スニペットの access_token
変数は、認可されているユーザーの代わりに API リクエストを行うために取得したトークンを表します。この完全な例は、トークンをブラウザのローカル ストレージに格納し、API リクエスト時にトークンを取得する方法を示しています。
var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://www.googleapis.com/drive/v3/about?fields=user&' + 'access_token=' + params['access_token']); xhr.onreadystatechange = function (e) { console.log(xhr.response); }; xhr.send(null);
完全なサンプルコード
OAuth 2.0 エンドポイント
このコードサンプルは、JavaScript 用の Google API クライアント ライブラリを使用せずに、JavaScript で OAuth 2.0 フローを完了する方法を示しています。このコードは、API リクエストを試行するボタンを表示する HTML ページ用です。ボタンをクリックすると、コードは、ページの API アクセス トークンがブラウザのローカル ストレージに保存されているかどうかを確認します。一致する場合、API リクエストが実行されます。それ以外の場合は、OAuth 2.0 フローが開始されます。
OAuth 2.0 フローの場合、このページは次の手順を実行します。
- ユーザーは Google の OAuth 2.0 サーバーに誘導され、そのサーバーが
https://www.googleapis.com/auth/drive.metadata.readonly
スコープへのアクセスをリクエストします。 - リクエストされた 1 つ以上のスコープへのアクセスを許可(または拒否)すると、ユーザーは元のページにリダイレクトされます。そこでは、フラグメント識別子文字列からアクセス トークンが解析されます。
このページは、アクセス トークンを使用してサンプル API リクエストを行います。
API リクエストは、Drive API の
about.get
メソッドを呼び出して、承認済みユーザーの Google ドライブ アカウントに関する情報を取得します。- リクエストが正常に実行されると、API レスポンスがブラウザのデバッグ コンソールに記録されます。
アプリへのアクセス権は、Google アカウントの [権限] ページで取り消すことができます。アプリは Google API ドキュメントの OAuth 2.0 デモとして表示されます。
このコードをローカルで実行するには、認可認証情報に対応する YOUR_CLIENT_ID
変数と YOUR_REDIRECT_URI
変数の値を設定する必要があります。YOUR_REDIRECT_URI
変数は、ページが提供されているのと同じ URL に設定する必要があります。この値は、 API Console Credentials pageで構成した OAuth 2.0 クライアントで承認済みのリダイレクト URI のいずれかと完全に一致している必要があります。この値が承認済みの URI と一致しない場合、redirect_uri_mismatch
エラーが発生します。また、プロジェクトでこのリクエストに対して適切な API を有効にする必要があります。
<html><head></head><body> <script> var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE'; var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE'; var fragmentString = location.hash.substring(1); // Parse query string to see if page request is coming from OAuth 2.0 server. var params = {}; var regex = /([^&=]+)=([^&]*)/g, m; while (m = regex.exec(fragmentString)) { params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]); } if (Object.keys(params).length > 0) { localStorage.setItem('oauth2-test-params', JSON.stringify(params) ); if (params['state'] && params['state'] == 'try_sample_request') { trySampleRequest(); } } // If there's an access token, try an API request. // Otherwise, start OAuth 2.0 flow. function trySampleRequest() { var params = JSON.parse(localStorage.getItem('oauth2-test-params')); if (params && params['access_token']) { var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://www.googleapis.com/drive/v3/about?fields=user&' + 'access_token=' + params['access_token']); xhr.onreadystatechange = function (e) { if (xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.response); } else if (xhr.readyState === 4 && xhr.status === 401) { // Token invalid, so prompt for user permission. oauth2SignIn(); } }; xhr.send(null); } else { oauth2SignIn(); } } /* * Create form to request access token from Google's OAuth 2.0 server. */ function oauth2SignIn() { // Google's OAuth 2.0 endpoint for requesting an access token var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth'; // Create element to open OAuth 2.0 endpoint in new window. var form = document.createElement('form'); form.setAttribute('method', 'GET'); // Send as a GET request. form.setAttribute('action', oauth2Endpoint); // Parameters to pass to OAuth 2.0 endpoint. var params = {'client_id': YOUR_CLIENT_ID, 'redirect_uri': YOUR_REDIRECT_URI, 'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly', 'state': 'try_sample_request', 'include_granted_scopes': 'true', 'response_type': 'token'}; // Add form parameters as hidden input values. for (var p in params) { var input = document.createElement('input'); input.setAttribute('type', 'hidden'); input.setAttribute('name', p); input.setAttribute('value', params[p]); form.appendChild(input); } // Add form to page and submit it to open the OAuth 2.0 endpoint. document.body.appendChild(form); form.submit(); } </script> <button onclick="trySampleRequest();">Try sample request</button> </body></html>
JavaScript 生成元の検証ルール
Google では、デベロッパーがアプリケーションの安全性を確保できるように、JavaScript のオリジンに次の検証ルールを適用しています。JavaScript 生成元は、これらのルールに準拠している必要があります。下記のドメイン、ホスト、スキームの定義については、RFC 3986 のセクション 3 をご覧ください。
検証ルール | |
---|---|
スキーム |
JavaScript 生成元では、プレーン HTTP ではなく HTTPS スキームを使用する必要があります。ローカルホスト URI(localhost IP アドレスの URI を含む)はこのルールから除外されます。 |
ホスト |
ホストに数値表記の IP アドレスを指定することはできません。ローカルホスト IP アドレスはこのルールから除外されます。 |
ドメイン |
“googleusercontent.com” にすることはできません。goo.gl など)を含めることはできません。 |
ユーザー情報 |
JavaScript 生成元に userinfo サブコンポーネントを含めることはできません。 |
[Path] |
JavaScript 生成元にパス コンポーネントを含めることはできません。 |
クエリ |
JavaScript 生成元にクエリ コンポーネントを含めることはできません。 |
Fragment |
JavaScript 生成元にフラグメント コンポーネントを含めることはできません。 |
キャラクター |
JavaScript 生成元には、次のような文字を含めることはできません。
|
段階的な承認
OAuth 2.0 プロトコルでは、アプリはリソースにアクセスするための承認をリクエストします。リソースへのアクセスはスコープで識別されます。ユーザーが必要なときにリソースの承認をリクエストすることは、ユーザー エクスペリエンスのベスト プラクティスであると考えられています。この手法を実現するため、Google の承認サーバーは増分承認をサポートしています。この機能を使用すると、必要に応じてスコープをリクエストできます。ユーザーが新しいスコープに対する権限を付与すると、認証コードが返されます。このコードは、ユーザーがプロジェクトに付与したすべてのスコープを含むトークンと交換される可能性があります。
たとえば、音楽トラックをサンプリングしてミックスを作成できるアプリでは、ログイン時に必要となるリソースはほとんどありませんが、ログインする人の名前以外は必要ないでしょう。ただし、完全なミックスを保存するには、Google ドライブへのアクセスが必要になります。ほとんどのユーザーにとって、Google ドライブへのアクセス権限を要求されるのはアプリが実際に必要であるときだけであれば、自然に感じられます。
この場合、ログイン時に、アプリが openid
スコープと profile
スコープをリクエストして基本的なログインを実行し、その後、最初のリクエストの時点で https://www.googleapis.com/auth/drive.file
スコープをリクエストして、ミックスを保存します。
増分承認から取得したアクセス トークンには、次のルールが適用されます。
- このトークンを使用して、新しく結合された承認に含まれるスコープのいずれかに対応するリソースにアクセスできます。
- 更新トークンを使用してアクセス トークンを取得する場合、アクセス トークンは結合された承認を表し、レスポンスに含まれる任意の
scope
値に使用できます。 - 組み合わせた承認には、ユーザーが API プロジェクトに付与したすべてのスコープが含まれます(異なるクライアントから付与がリクエストされた場合でも同様です)。たとえば、ユーザーがアプリケーションのデスクトップ クライアントを使用して 1 つのスコープへのアクセス権を付与し、さらにモバイル クライアントを介して同じアプリケーションに別のスコープを付与した場合、統合された承認には両方のスコープが含まれます。
- 統合された承認を表すトークンを取り消すと、関連するユーザーに代わってその承認のスコープへのすべてのアクセスが同時に取り消されます。
以下のコードサンプルは、既存のアクセス トークンにスコープを追加する方法を示しています。このアプローチにより、アプリは複数のアクセス トークンを管理する必要がなくなります。
OAuth 2.0 エンドポイント
既存のアクセス トークンにスコープを追加するには、Google の OAuth 2.0 サーバーへのリクエストに include_granted_scopes
パラメータを含めます。
次のコード スニペットは、その方法を示しています。このスニペットでは、アクセス トークンが有効なスコープがブラウザのローカル ストレージに保存されていることを前提としています。(この完全な例のコードでは、ブラウザのローカル ストレージに oauth2-test-params.scope
プロパティを設定することにより、アクセス トークンが有効なスコープのリストを保存しています)。
このスニペットは、アクセス トークンが有効なスコープと、特定のクエリに使用するスコープを比較します。アクセス トークンがそのスコープをカバーしていない場合、OAuth 2.0 フローが開始します。ここで、oauth2SignIn
関数は、ステップ 2 で提供された関数と同じです(これは後の完全な例で示されています)。
var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly'; var params = JSON.parse(localStorage.getItem('oauth2-test-params')); var current_scope_granted = false; if (params.hasOwnProperty('scope')) { var scopes = params['scope'].split(' '); for (var s = 0; s < scopes.length; s++) { if (SCOPE == scopes[s]) { current_scope_granted = true; } } } if (!current_scope_granted) { oauth2SignIn(); // This function is defined elsewhere in this document. } else { // Since you already have access, you can proceed with the API request. }
トークンの取り消し
場合によっては、ユーザーがアプリケーションに与えられたアクセス権の取り消しを希望することがあります。ユーザーは アカウント設定にアクセスしてアクセス権を取り消すことができます。詳しくは、サポート ドキュメント「アカウントにアクセスできるサードパーティのサイトやアプリのサイトやアプリのアクセス権の削除」をご覧ください。
また、アプリケーションに付与されているアクセス権をプログラムで取り消すこともできます。プログラムによる取り消しは、ユーザーがアプリケーションの登録を解除した場合や、アプリケーションを削除した場合、またはアプリに必要な API リソースが大幅に変更された場合などに重要です。つまり、削除プロセスに、以前にアプリに付与された権限を確実に削除するための API リクエストを含めることができます。
OAuth 2.0 エンドポイント
プログラムでトークンを取り消すには、アプリケーションは 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
がエラーコードとともに返されます。
次の JavaScript スニペットは、JavaScript 用 Google API クライアント ライブラリを使用せずに、JavaScript でトークンを取り消す方法を示しています。トークン取り消し用の Google の OAuth 2.0 エンドポイントはクロスオリジン リソース シェアリング(CORS)をサポートしていないため、リクエストは、XMLHttpRequest()
メソッドを使用してリクエストを送信するのではなく、フォームを作成してエンドポイントに送信します。
function revokeAccess(accessToken) { // Google's OAuth 2.0 endpoint for revoking access tokens. var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke'; // Create <form> element to use to POST data to the OAuth 2.0 endpoint. var form = document.createElement('form'); form.setAttribute('method', 'post'); form.setAttribute('action', revokeTokenEndpoint); // Add access token to the form so it is set as value of 'token' parameter. // This corresponds to the sample curl request, where the URL is: // https://oauth2.googleapis.com/revoke?token={token} var tokenField = document.createElement('input'); tokenField.setAttribute('type', 'hidden'); tokenField.setAttribute('name', 'token'); tokenField.setAttribute('value', accessToken); form.appendChild(tokenField); // Add form to page and submit it to actually revoke the token. document.body.appendChild(form); form.submit(); }