JavaScript ウェブ アプリケーションに OAuth 2.0 を使用する

このドキュメントでは、JavaScript ウェブ アプリケーションから YouTube Data API にアクセスするための OAuth 2.0 認証を実装する方法について説明します。OAuth 2.0 を使用すると、ユーザー名やパスワードなどの情報を非公開にしたまま、特定のデータをアプリケーションと共有できます。 たとえば、OAuth 2.0 を使用して、ユーザーの YouTube チャンネルに動画をアップロードする権限を取得できます。

この OAuth 2.0 フローは、暗黙的権限付与フローと呼ばれます。ユーザーがアプリケーションを使用しているときにのみ API にアクセスするアプリ向けに設計されています。これらのアプリケーションで機密情報を保存することはできません。

このフローでは、アプリが Google URL を開き、クエリ パラメータを使用して、アプリとアプリに必要な API アクセスのタイプを識別します。この URL は、現在のブラウザ ウィンドウまたはポップアップで開くことができます。ユーザーは Google で認証を行い、リクエストされた権限を付与できます。その後、ユーザーをアプリにリダイレクトします。リダイレクトにはアクセス トークンが含まれます。アプリはこのトークンを検証し、API リクエストに使用します。

Google API クライアント ライブラリと Google Identity Services

JavaScript 用の Google API クライアント ライブラリを使用して Google への承認された呼び出しを行う場合は、 Google Identity Services JavaScript ライブラリを使用して OAuth 2.0 フローを処理する必要があります。Google ID サービスのトークンモデルをご覧ください。これは、OAuth 2.0 の暗黙的権限付与フローに基づいています。

前提条件

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

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

プロジェクトで 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. フォームに入力します。JavaScript を使用して承認済みの Google API リクエストを行うアプリケーションでは、承認済みの JavaScript 生成元を指定する必要があります。オリジンは、アプリケーションが OAuth 2.0 サーバーにリクエストを送信できるドメインを識別します。これらのオリジンは Google の検証ルールに準拠している必要があります。

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

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

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 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 サーバーがユーザーをリダイレクトする場所を指定します。この値は、クライアントの API Console Credentials pageで構成した OAuth 2.0 クライアントで承認済みのリダイレクト URI のいずれかと完全に一致する必要があります。この値が、指定された client_id に承認済みのリダイレクト URI と一致しない場合は、redirect_uri_mismatch エラーが発生します。

http または https のスキーム、大文字と小文字、末尾のスラッシュ(「/」)がすべて一致している必要があります。

response_type 必須

JavaScript アプリケーションでは、このパラメータの値を token に設定する必要があります。この値は、認可プロセスの完了後にユーザーがリダイレクトされる URI(#)のフラグメント識別子のアクセス トークンを name=value ペアとして返すよう Google 承認サーバーに指示します。

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 チャンネルの個人情報の表示

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

可能な限り、コンテキストに応じて承認スコープへのアクセスをアプリケーションからリクエストすることをおすすめします。段階的承認により、状況に応じてユーザーデータへのアクセスをリクエストすると、アプリがそのアクセスを必要とする理由をユーザーが簡単に理解できるようになります。

state 推奨

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

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

include_granted_scopes 省略可

アプリケーションは増分認証を使用して、コンテキストに応じて追加のスコープへのアクセスをリクエストできます。このパラメータの値を true に設定し、承認リクエストが付与されると、新しいアクセス トークンには、ユーザーが以前にアプリケーションへのアクセスを許可したスコープも含まれます。例については、増分承認セクションをご覧ください。

login_hint 省略可

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

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

prompt 省略可

ユーザーに提示するプロンプトのスペース区切りリスト(大文字と小文字を区別)。このパラメータを指定しない場合は、プロジェクトが初めてアクセスをリクエストしたときにのみ、ユーザーにメッセージが表示されます。詳しくは、 再同意を求めるをご覧ください。

指定できる値は次のとおりです。

none 認証画面や同意画面を表示しません。他の値と一緒に指定することはできません。
consent ユーザーに同意を求めます。
select_account アカウントの選択を求めるメッセージを表示します。

Google の承認サーバーへのリダイレクトの例

次のサンプル URL は、ユーザーの YouTube アカウントを表示するアクセスを許可するスコープへのオフライン アクセス(access_type=offline)をリクエストします。段階的な承認を使用して、ユーザーが以前にアプリケーションへのアクセスを許可したスコープを新しいアクセス トークンがカバーするようにします。この URL では、必須の redirect_uri パラメータ、response_type パラメータ、client_id パラメータと state パラメータの値も設定します。読みやすくするために、URL には改行とスペースが含まれています。

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&
 include_granted_scopes=true&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 response_type=token&
 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/youtube.force-ssl',
                '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 の Android 用 AppAuth などの Android ライブラリを使用する必要があります。

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

iOS

iOS や macOS のデベロッパーが WKWebView で承認リクエストを開くと、このエラーが発生することがあります。デベロッパーは、代わりに iOS 用の Google ログインや OpenID Foundation の iOS 用 AppAuth などの 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%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&
 include_granted_scopes=true&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 response_type=token&
 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 の呼び出しをセットアップできます(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

JavaScript サンプルコード

以下のコード スニペットは、CORS(クロスオリジン リソース シェアリング)を使用して Google API にリクエストを送信する方法を示しています。この例では、JavaScript 用の Google API クライアント ライブラリは使用しません。ただし、クライアント ライブラリを使用していない場合でも、そのライブラリのドキュメントにある CORS サポート ガイドをご覧いただくと、これらのリクエストについての理解を深めることができます。

このコード スニペットでは、access_token 変数が、承認済みユーザーの代わりに API リクエストを行うために取得したトークンを表します。完全な例は、そのトークンをブラウザのローカル ストレージに格納し、API リクエストの際にトークンを取得する方法を示しています。

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true&' +
    '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 フローの場合、ページの手順は次のとおりです。

  1. これにより、ユーザーは Google の OAuth 2.0 サーバーにリダイレクトされ、サーバーは https://www.googleapis.com/auth/youtube.force-ssl スコープへのアクセスをリクエストします。
  2. リクエストされた 1 つ以上のスコープへのアクセスを許可(または拒否)すると、ユーザーは元のページにリダイレクトされ、そこでフラグメント識別子文字列からアクセス トークンが解析されます。
  3. このページは、アクセス トークンを使用してサンプル API リクエストを行います。

    この API リクエストは、YouTube Data API の channels.list メソッドを呼び出して、承認済みユーザーの YouTube チャンネルに関するデータを取得します。

  4. リクエストが正常に実行されると、API レスポンスがブラウザのデバッグ コンソールに記録されます。

Google アカウントの [権限] ページで、アプリへのアクセス権を取り消すことができます。アプリは OAuth 2.0 Demo for Google API Docs として表示されます。

このコードをローカルで実行するには、認可認証情報に対応する YOUR_CLIENT_ID 変数と YOUR_REDIRECT_URI 変数の値を設定する必要があります。YOUR_REDIRECT_URI 変数は、ページが提供されている URL と同じ 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/youtube/v3/channels?part=snippet&mine=true&' +
          '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/youtube.force-ssl',
                  '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 を含む)は、このルールから除外されます。

ホスト

ホストに raw IP アドレスを指定することはできません。ローカルホストの IP アドレスはこのルールから除外されます。

ドメイン
  • ホスト TLD(トップレベル ドメイン)は、パブリック サフィックス リストに属している必要があります。
  • ホストドメインを “googleusercontent.com” にすることはできません。
  • JavaScript 生成元に、アプリがそのドメインを所有していない限り、短縮 URL ドメイン(goo.gl など)を含めることはできません。
  • ユーザー情報

    JavaScript 生成元に userinfo サブコンポーネントを含めることはできません。

    [Path]

    JavaScript 生成元にパス コンポーネントを含めることはできません。

    クエリ

    JavaScript オリジンにクエリ コンポーネントを含めることはできません。

    Fragment

    JavaScript 生成元にフラグメント コンポーネントを含めることはできません。

    文字数 JavaScript 生成元には、次のような文字を含めることはできません。
    • ワイルドカード文字('*'
    • 印刷不可能な ASCII 文字
    • 無効なパーセント エンコード(パーセント記号の後に 2 桁の 16 進数が続く URL エンコード形式に一致しないパーセント エンコード)
    • null 文字(エンコードされた NULL 文字。例:%00%C0%80

    段階的な承認

    OAuth 2.0 プロトコルでは、アプリはスコープで識別されるリソースにアクセスするための承認をリクエストします。リソースが必要になったときに承認をリクエストするのが、ユーザー エクスペリエンスの最良のプラクティスと考えられています。この手法を実現するために、Google の承認サーバーは増分承認をサポートしています。この機能を使用すると、必要に応じてスコープをリクエストできます。ユーザーが新しいスコープの権限を付与すると、ユーザーがプロジェクトに許可したすべてのスコープを含むトークンと交換できる認証コードが返されます。

    たとえば、ユーザーが地域の興味深いイベントを見つけるのに役立つアプリがあるとします。ユーザーは、このアプリを使用して、イベントに関する動画を視聴し、動画を評価し、再生リストに動画を追加することができます。また、アプリを使用して Google カレンダーに予定を追加することもできます。

    この場合、ログイン時に、アプリはスコープへのアクセスを不要またはリクエストしない可能性があります。ただし、ユーザーが動画の評価、再生リストへの動画の追加、別の YouTube アクションを実行しようとした場合、アプリは https://www.googleapis.com/auth/youtube.force-ssl スコープへのアクセスをリクエストする可能性があります。同様に、ユーザーがカレンダーの予定を追加しようとした場合、アプリは https://www.googleapis.com/auth/calendar スコープへのアクセスをリクエストできます。

    増分承認から取得したアクセス トークンには、次のルールが適用されます。

    • このトークンを使用して、新しい組み合わせの承認に含まれるスコープのいずれかに対応するリソースにアクセスできます。
    • 結合された認可の更新トークンを使用してアクセス トークンを取得する場合、アクセス トークンは結合された認可を表し、レスポンスに含まれる任意の scope 値に使用できます。
    • 統合された承認には、ユーザーが API プロジェクトに許可したすべてのスコープが含まれます。異なるクライアントから権限付与がリクエストされた場合も同様です。たとえば、ユーザーがアプリケーションのデスクトップ クライアントを使用して 1 つのスコープへのアクセスを許可し、その後モバイル クライアントを介して同じアプリケーションに別のスコープを付与した場合、統合された承認には両方のスコープが含まれることになります。
    • 統合された承認を表すトークンを取り消すと、関連するユーザーに代わって、その承認のスコープに対するすべてのアクセス権が同時に取り消されます。

    以下のコードサンプルは、既存のアクセス トークンにスコープを追加する方法を示しています。この方法により、アプリで複数のアクセス トークンを管理する必要がなくなります。

    OAuth 2.0 エンドポイント

    この例では、呼び出し元のアプリケーションが、ユーザーの YouTube アナリティクス データを取得するためのアクセス権をリクエストしています。さらに、ユーザーがすでにアプリケーションに付与したアクセス権もリクエストしています。

    既存のアクセス トークンにスコープを追加するには、Google の OAuth 2.0 サーバーへのリクエストinclude_granted_scopes パラメータを含めます。

    次のコード スニペットは、その方法を示しています。このスニペットは、アクセス トークンが有効なスコープがブラウザのローカル ストレージに保存されていることを前提としています。(完全な例のコードでは、ブラウザのローカル ストレージに oauth2-test-params.scope プロパティを設定することで、アクセス トークンが有効なスコープのリストを保存しています)。

    このスニペットは、アクセス トークンが有効なスコープと、特定のクエリに使用するスコープを比較します。アクセス トークンがそのスコープに含まれない場合、OAuth 2.0 フローが開始されます。ここで、oauth2SignIn 関数は、ステップ 2 で提供された関数と同じです(後の完全な例で説明します)。

    var SCOPE = 'https://www.googleapis.com/auth/youtube.force-ssl';
    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();
    }