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

このドキュメントでは、ウェブサーバー アプリケーションが Google API クライアント ライブラリまたは Google OAuth 2.0 エンドポイントを使用して OAuth 2.0 認証を実装し、YouTube Analytics API または YouTube Reporting API にアクセスする方法について説明します。

OAuth 2.0 を使用すると、ユーザー名やパスワードなどの情報を非公開にしたまま、特定のデータをアプリケーションと共有することができます。たとえば、アプリケーションは OAuth 2.0 を使用して、チャンネルの YouTube アナリティクス データを取得する権限を取得できます。

この OAuth 2.0 フローはユーザー認証専用です。機密情報を保存し、状態を維持できるアプリケーション向けに設計されています。適切に承認されたウェブサーバー アプリケーションは、ユーザーがアプリケーションを操作している間、またはユーザーがアプリケーションを離れた後で、API にアクセスできます。

また、ウェブサーバー アプリケーションでは、特に Cloud APIs を呼び出してユーザー固有のデータではなくプロジェクト ベースのデータにアクセスする場合に、API リクエストを承認するために サービス アカウントを使用することがよくあります。ウェブサーバー アプリケーションは、ユーザー承認と組み合わせてサービス アカウントを使用できます。

  • YouTube Analytics API は、サービス アカウントのフローをサポートしていません。
  • YouTube Reporting API は、複数の YouTube チャンネルを所有、管理する YouTube コンテンツ所有者向けのサービス アカウントのフローのみをサポートしています。具体的には、コンテンツ所有者は、onBehalfOfContentOwner リクエスト パラメータの値を設定する API リクエストでサービス アカウントを使用できます。

クライアント ライブラリ

このページの言語固有の例では、Google API クライアント ライブラリを使用して OAuth 2.0 認証を実装しています。コードサンプルを実行するには、まず、ご使用の言語のクライアント ライブラリをインストールする必要があります。

Google API クライアント ライブラリを使用してアプリケーションの OAuth 2.0 フローを処理すると、アプリケーションが独自に処理する必要がある多くのアクションがクライアント ライブラリによって実行されます。たとえば、保存されたアクセス トークンをアプリケーションが使用または更新できるタイミングや、アプリケーションが同意を再取得する必要があるタイミングを決定します。また、クライアント ライブラリは正しいリダイレクト URL を生成し、認証コードをアクセス トークンと交換するリダイレクト ハンドラの実装に役立ちます。

サーバーサイド アプリケーション用の Google API クライアント ライブラリは、以下の言語で利用できます。

前提条件

プロジェクトで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 Analytics API と YouTube Reporting API を見つけて有効にします。YouTube アナリティクスのデータを取得する多くのアプリケーションも、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. フォームに入力し、[作成] をクリックします。PHP、Java、Python、Ruby、.NET などの言語やフレームワークを使用するアプリケーションでは、承認済みのリダイレクト URI を指定する必要があります。リダイレクト URI は、OAuth 2.0 サーバーがレスポンスを送信できるエンドポイントです。これらのエンドポイントは、Google の検証ルールに準拠している必要があります。

    テスト用に、ローカルマシンを参照する URI(http://localhost:8080 など)を指定できます。この点を念頭に置いて、このドキュメントのすべての例でリダイレクト URI として http://localhost:8080 を使用しています。

    アプリケーションがページの他のリソースに認証コードを公開しないように、アプリの認証エンドポイントを設計することをおすすめします。

認証情報を作成したら、 API Consoleから client_secret.json ファイルをダウンロードします。そのアプリケーションだけがアクセスできる場所にファイルを安全に保存します。

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

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

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

また、アプリケーションは認可スコープへのアクセスを、段階的な認可プロセスを通じてリクエストすることをおすすめします。このプロセスでは、状況に応じて、アプリケーションからユーザーデータへのアクセスをリクエストします。このベスト プラクティスは、アプリケーションがリクエストしているアクセス権を必要とする理由をユーザーが容易に理解するうえで役立ちます。

YouTube Analytics API では、次のスコープを使用します。

スコープ
https://www.googleapis.com/auth/youtube YouTubeアカウントを管理する
https://www.googleapis.com/auth/youtube.readonly YouTubeアカウントを表示する
https://www.googleapis.com/auth/youtubepartner YouTubeでアセ��トと関連コンテンツを表示および管理する
https://www.googleapis.com/auth/yt-analytics-monetary.readonly YouTubeコンテンツの金銭的および非金銭的なYouTubeAnalyticsレポートを表示する
https://www.googleapis.com/auth/yt-analytics.readonly YouTubeコンテンツのYouTubeAnalyticsレポートを表示する

YouTube Reporting API では次のスコープを使用します。

スコープ
https://www.googleapis.com/auth/yt-analytics-monetary.readonly YouTubeコンテンツの金銭的および非金銭的なYouTubeAnalyticsレポートを表示する
https://www.googleapis.com/auth/yt-analytics.readonly YouTubeコンテンツのYouTubeAnalyticsレポートを表示する

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

言語固有の要件

このドキュメントのコードサンプルを実行するには、Google アカウント、インターネットへのアクセス、ウェブブラウザが必要です。いずれかの API クライアント ライブラリを使用している場合は、以下の言語固有の要件もご覧ください。

PHP

このドキュメントの PHP コードサンプルを実行するには、次のものが必要です。

  • PHP 5.6 以降(コマンドライン インターフェース(CLI)と JSON 拡張機能がインストール済み)
  • Composer 依存関係管理ツール。
  • PHP の Google API クライアント ライブラリ:

    composer require google/apiclient:^2.10

Python

このドキュメントの Python コードサンプルを実行するには、次のものが必要です。

  • Python 2.6 以降
  • pip パッケージ管理ツール。
  • Python 用の Google API クライアント ライブラリ:
    pip install --upgrade google-api-python-client
  • ユーザー承認用の google-authgoogle-auth-oauthlibgoogle-auth-httplib2
    pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
  • Flask Python ウェブ アプリケーション フレームワーク。
    pip install --upgrade flask
  • requests HTTP ライブラリ。
    pip install --upgrade requests

Ruby

このドキュメントの Ruby コードサンプルを実行するには、次のものが必要です。

  • Ruby 2.6 以降
  • Ruby 用 Google 認証ライブラリ:

    gem install googleauth
  • Sinatra Ruby ウェブ アプリケーション フレームワーク。

    gem install sinatra

Node.js

このドキュメントの Node.js コードサンプルを実行するには、次のものが必要です。

  • メンテナンスの LTS、アクティブな LTS、または Node.js の現在のリリース。
  • Google API Node.js クライアント:

    npm install googleapis crypto express express-session

HTTP/REST

ライブラリをインストールしなくても、OAuth 2.0 エンドポイントを直接呼び出せます。

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

次の手順は、アプリケーションが Google の OAuth 2.0 サーバーと連携し、ユーザーの代わりに API リクエストを実行することについてユーザーの同意を取得する方法を示しています。ユーザーの承認が必要な Google API リクエストをアプリケーションで実行するには、アプリケーションでその同意を得る必要があります。

以下に、この手順の概要を示します。

  1. アプリケーションで必要な権限を特定します。
  2. アプリは、リクエストされた権限のリストとともにユーザーを Google にリダイレクトします。
  3. この権限をアプリケーションに付与するかどうかは、ユーザーが決定します。
  4. アプリケーションで、ユーザーが決定した内容を確認します。
  5. リクエストされた権限をユーザーが許可した場合、アプリケーションはユーザーの代わりに API リクエストを行うために必要なトークンを取得します。

ステップ 1: 認可パラメータを設定する

最初のステップは、承認リクエストを作成することです。このリクエストでは、アプリを識別し、ユーザーがアプリに付与するよう求められる権限を定義するパラメータを設定します。

  • OAuth 2.0 の認証と認可に Google クライアント ライブラリを使用する場合は、これらのパラメータを定義するオブジェクトを作成して構成します。
  • Google OAuth 2.0 エンドポイントを直接呼び出す場合は、URL を生成し、その URL にパラメータを設定します。

以下のタブでは、ウェブサーバー アプリケーションでサポートされる認可パラメータを定義します。言語別のサンプルでは、クライアント ライブラリまたは認可ライブラリを使用して、これらのパラメータを設定するオブジェクトを構成する方法も示しています。

PHP

以下のコード スニペットは、認可リクエストのパラメータを定義する Google\Client() オブジェクトを作成します。

このオブジェクトは、client_secret.json ファイルの情報を使用してアプリケーションを識別します。(このファイルの詳細については、認証情報の作成をご覧ください)。このオブジェクトでは、アプリケーションがアクセス権限をリクエストしているスコープと、Google の OAuth 2.0 サーバーからのレスポンスを処理するアプリケーションの認証エンドポイントへの URL も識別されます。最後に、オプションの access_type パラメータと include_granted_scopes パラメータを設定します。

たとえば、ユーザーの YouTube アナリティクス レポートを取得するためにオフライン アクセスをリクエストするには、次のようにします。

$client = new Google\Client();

// Required, call the setAuthConfig function to load authorization credentials from
// client_secret.json file.
$client->setAuthConfig('client_secret.json');

// Required, to set the scope value, call the addScope function
$client->addScope(Google_Service_YouTubeAnalytics::YT_ANALYTICS_READONLY);

// Required, call the setRedirectUri function to specify a valid redirect URI for the
// provided client_id
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');

// Recommended, offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');

// Recommended, call the setState function. Using a state value can increase your assurance that
// an incoming connection is the result of an authentication request.
$client->setState($sample_passthrough_value);

// Optional, if your application knows which user is trying to authenticate, it can use this
// parameter to provide a hint to the Google Authentication Server.
$client->setLoginHint('hint@example.com');

// Optional, call the setPrompt function to set "consent" will prompt the user for consent
$client->setPrompt('consent');

// Optional, call the setIncludeGrantedScopes function with true to enable incremental
// authorization
$client->setIncludeGrantedScopes(true);

Python

次のコード スニペットでは、google-auth-oauthlib.flow モジュールを使用して承認リクエストを作成しています。

このコードは、認証情報の作成後にダウンロードした client_secret.json ファイルからの情報を使用してアプリケーションを識別する Flow オブジェクトを作成します。このオブジェクトは、アプリケーションがアクセス権限をリクエストしているスコープと、Google の OAuth 2.0 サーバーからのレスポンスを処理するアプリケーションの認証エンドポイントへの URL も識別します。最後に、オプションの access_type パラメータと include_granted_scopes パラメータを設定します。

たとえば、ユーザーの YouTube アナリティクス レポートを取得するためにオフライン アクセスをリクエストするには、次のようにします。

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Required, call the from_client_secrets_file method to retrieve the client ID from a
# client_secret.json file. The client ID (from that file) and access scopes are required. (You can
# also use the from_client_config method, which passes the client configuration as it originally
# appeared in a client secrets file but doesn't access the file itself.)
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/yt-analytics.readonly'])

# Required, indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
flow.redirect_uri = 'https://www.example.com/oauth2callback'

# Generate URL for request to Google's OAuth 2.0 server.
# Use kwargs to set optional request parameters.
authorization_url, state = flow.authorization_url(
    # Recommended, enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type='offline',
    # Optional, enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true',
    # Optional, if your application knows which user is trying to authenticate, it can use this
    # parameter to provide a hint to the Google Authentication Server.
    login_hint='hint@example.com',
    # Optional, set prompt to 'consent' will prompt the user for consent
    prompt='consent')

Ruby

作成した client_secrets.json ファイルを使用して、アプリケーションでクライアント オブジェクトを構成します。クライアント オブジェクトを構成するときは、アプリケーションがアクセスする必要があるスコープと、OAuth 2.0 サーバーからのレスポンスを処理するアプリケーションの認証エンドポイントへの URL を指定します。

たとえば、ユーザーの YouTube アナリティクス レポートを取得するためにオフライン アクセスをリクエストするには、次のようにします。

require 'google/apis/youtube_analytics_v1'
require "googleauth"
require 'googleauth/stores/redis_token_store'

client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')
scope = 'https://www.googleapis.com/auth/yt-analytics.readonly'
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')

アプリケーションはこのクライアント オブジェクトを使用して、認可リクエスト URL の生成や HTTP リクエストへのアクセス トークンの適用などの OAuth 2.0 オペレーションを実行します。

Node.js

次のコード スニペットは、認可リクエストのパラメータを定義する google.auth.OAuth2 オブジェクトを作成します。

このオブジェクトは、client_secret.json ファイルからの情報を使用してアプリケーションを識別します。アクセス トークンを取得するためにユーザーに権限をリクエストするには、ユーザーを同意ページにリダイレクトします。同意ページの URL を作成するには:

const {google} = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
 * from the client_secret.json file. To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a secure random state value.
const state = crypto.randomBytes(32).toString('hex');

// Store state in the session
req.session.state = state;

// Generate a url that asks permissions for the Drive activity scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true,
  // Include the state parameter to reduce the risk of CSRF attacks.
  state: state
});

重要な注意事項 - refresh_token は最初の承認時にのみ返されます。詳しくは、 こちらをご覧ください。

HTTP/REST

Google の OAuth 2.0 エンドポイントは https://accounts.google.com/o/oauth2/v2/auth にあ��ます。このエンドポイントには 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 必須

Google OAuth 2.0 エンドポイントが認証コードを返すかどうかを決定します。

ウェブサーバー アプリケーションのパラメータ値を code に設定します。

scope 必須

ユーザーの代わりにアプリケーションがアクセスできるリソースを識別するスコープをスペースで区切ったリスト。これらの値は、Google がユーザーに表示する同意画面を通知します。

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

YouTube Analytics API では、次のスコープを使用します。

スコープ
https://www.googleapis.com/auth/youtube YouTubeアカウントを管理する
https://www.googleapis.com/auth/youtube.readonly YouTubeアカウントを表示する
https://www.googleapis.com/auth/youtubepartner YouTubeでアセットと関連コンテンツを表示および管理する
https://www.googleapis.com/auth/yt-analytics-monetary.readonly YouTubeコンテンツの金銭的および非金銭的なYouTubeAnalyticsレポートを表示する
https://www.googleapis.com/auth/yt-analytics.readonly YouTubeコンテンツのYouTubeAnalyticsレポートを表示する

YouTube Reporting API では次のスコープを使用します。

スコープ
https://www.googleapis.com/auth/yt-analytics-monetary.readonly YouTubeコンテンツの金銭的および非金銭的なYouTubeAnalyticsレポートを表示する
https://www.googleapis.com/auth/yt-analytics.readonly YouTubeコンテンツのYouTubeAnalyticsレポートを表示する

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

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

access_type 推奨

ユーザーがブラウザに存在しないときに、アプリケーションがアクセス トークンを更新できるかどうかを示します。有効なパラメータ値は、デフォルト値の onlineoffline です。

ユーザーがブラウザにいないときにアプリケーションでアクセス トークンを更新する必要がある場合は、値を offline に設定します。こ���は、このドキュメントで後述するアクセス トークンを更新する方法です。この値は、アプリケーションがトークンと最初に認証コードを交換するときに、更新トークンとアクセス トークンを返すように Google 認可サーバーに指示します。

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 アカウントの選択をユーザーに促します。

ステップ 2: Google の OAuth 2.0 サーバーにリダイレクトする

ユーザーを Google の OAuth 2.0 サーバーにリダイレクトして、認証と認可のプロセスを開始します。通常これは、アプリケーションが最初にユーザーのデータにアクセスする必要があるときに行われます。段階的な承認の場合、アプリがまだアクセス権限を持っていない追加のリソースに初めてアクセスする必要がある場合にも、このステップが行われます。

PHP

  1. Google の OAuth 2.0 サーバーからアクセスをリクエストするための URL を生成します。
    $auth_url = $client->createAuthUrl();
  2. ユーザーを $auth_url にリダイレクトします。
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

次の例は、Flask ウェブ アプリケーション フレームワークを使用してユーザーを認証 URL にリダイレクトする方法を示しています。

return flask.redirect(authorization_url)

Ruby

  1. Google の OAuth 2.0 サーバーからアクセスをリクエストする URL を生成します。
    auth_uri = authorizer.get_authorization_url(login_hint: user_id, request: request)
  2. ユーザーを auth_uri にリダイレクトします。

Node.js

  1. ステップ 1 で生成された URL authorizationUrlgenerateAuthUrl メソッドを使用して、Google の OAuth 2.0 サーバーからアクセスをリクエストします。
  2. ユーザーを authorizationUrl にリダイレクトします。
    res.redirect(authorizationUrl);

HTTP/REST

Sample redirect to Google's authorization server

The sample URL below requests offline access (access_type=offline) to a scope that permits access to retrieve the user's YouTube Analytics reports. It uses incremental authorization to ensure that the new access token covers any scopes to which the user previously granted the application access. The URL also sets values for the required redirect_uri, response_type, and client_id parameters as well as for the state parameter. The URL contains line breaks and spaces for readability.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly&
 access_type=offline&
 include_granted_scopes=true&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 response_type=code&
 client_id=client_id

リクエスト URL を作成したら、ユーザーをその URL にリダイレクトします。

Google の OAuth 2.0 サーバーがユーザーを認証し、リクエストされたスコープにアプリケーションがアクセスすることについてユーザーから同意を得ます。レスポンスは、指定したリダイレクト URL を使用してアプリケーションに返されます。

ステップ 3: Google がユーザーに同意を求める

このステップでは、要求されたアクセス権をアプリケーションに付与するかどうかをユーザーが決定します。この段階で、Google は同意ウィンドウを表示します。このウィンドウには、ユーザーの認証情報を使用してアクセス権限をリクエストしているアプリケーションと Google API サービスの名前と、付与するアクセス スコープの概要が表示されます。これにより、ユーザーは、アプリケーションからリクエストされた 1 つ以上のスコープへのアクセス権を付与することに同意するか、リクエストを拒否することができます。

この段階では、アプリケーションはアクセス権が付与されたかどうかを示す Google の OAuth 2.0 サーバーからのレスポンスを待つため、何もする必要はありません。このレスポンスについては、次の手順で説明します。

エラー

Google の OAuth 2.0 認可エンドポイントへのリクエストで、想定される認証と認可のフローではなく、ユーザー向けのエラー メッセージが表示されることがあります。一般的なエラーコードと推奨される解決策を以下に示します。

admin_policy_enforced

Google Workspace 管理者のポリシーにより、Google アカウントでリクエストされた 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

OAuth クライアント シークレットが正しくありません。このリクエストで使用するクライアント ID とシークレットなど、OAuth クライアント構成を確認します。

invalid_grant

アクセス トークンを更新した場合、または増分認証を使用した場合、トークンが期限切れであるか、無効になっている可能性があります。ユーザーを再度認証し、新しいトークンを取得するためのユーザーの同意を求めます。このエラーが引き続き表示される場合は、アプリケーションが正しく構成されていることと、リクエストで正しいトークンとパラメータを使用していることを確認してください。それ以外の場合は、ユーザー アカウントが削除または無効化されている可能性があります。

redirect_uri_mismatch

認可リクエストで渡された redirect_uri が、OAuth クライアント ID の承認済みのリダイレクト URI と一致しない。 Google API Console Credentials pageで承認済みのリダイレクト URI を確認します。

redirect_uri パラメータは、非推奨でサポートされなくなった OAuth 帯域外(OOB)フローを指す場合があります。統合を更新するには、移行ガイドをご覧ください。

invalid_request

リクエストになんらかの問題がありました。これには、いくつかの理由が考えられます。

  • リクエストの形式が正しくありません
  • リクエストに必須パラメータが含まれていませんでした
  • リクエストで、Google でサポートされていない認証方法が使用されています。OAuth 統合で推奨の統合方法が使用されていることを確認する

ステップ 4: OAuth 2.0 サーバー レスポンスを処理する

OAuth 2.0 サーバーは、リクエストで指定された URL を使用して、アプリケーションのアクセス リクエストに応答します。

ユーザーがアクセス リクエストを承認すると、レスポンスに認証コードが含まれます。ユーザーがリクエストを承認しない場合、レスポンスにはエラー メッセージが含まれます。ウェブサーバーに返される認証コードやエラー メッセージは、次のようにクエリ文字列に表示��れます。

エラー レスポンス:

https://oauth2.example.com/auth?error=access_denied

認証コードのレスポンス:

https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7

OAuth 2.0 サーバー レスポンスの例

このフローをテストするには、次のサンプル URL をクリックします。この URL は、Google ドライブ内のファイルのメタデータを表示するための読み取り専用アクセスをリクエストします。

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly&
 access_type=offline&
 include_granted_scopes=true&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 response_type=code&
 client_id=client_id

OAuth 2.0 フローを完了すると、http://localhost/oauth2callback にリダイレクトされます。リダイレクトされると、ローカルマシンがそのアドレスでファイルを提供しない限り、404 NOT FOUND エラーが発生する可能性があります。次のステップでは、ユーザーがアプリケーションにリダイレクトされたときに URI で返される情報の詳細を説明します。

ステップ 5: 更新トークンとアクセス トークンに認証コードを交換する

ウェブサーバーは、認証コードを受け取った後、その認証コードをアクセス トークンと交換できます。

PHP

認証コードをアクセス トークンと交換するには、authenticate メソッドを使用します。

$client->authenticate($_GET['code']);

アクセス トークンは、getAccessToken メソッドを使用して取得できます。

$access_token = $client->getAccessToken();

Python

コールバック ページで、google-auth ライブラリを使用して認可サーバーのレスポンスを確認します。次に、flow.fetch_token メソッドを使用して、そのレスポンスの認証コードをアクセス トークンと交換します。

state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/yt-analytics.readonly'],
    state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)

# Store the credentials in the session.
# ACTION ITEM for developers:
#     Store user's access and refresh tokens in your data store if
#     incorporating this code into your real app.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'token_uri': credentials.token_uri,
    'client_id': credentials.client_id,
    'client_secret': credentials.client_secret,
    'scopes': credentials.scopes}

Ruby

コールバック ページで、googleauth ライブラリを使用して認可サーバーのレスポンスを確認します。authorizer.handle_auth_callback_deferred メソッドを使用して認証コードを保存し、最初に承認をリクエストした URL にリダイレクトします。これにより、ユーザーのセッションに結果を一時的に格納して、コードの交換を延期します。

  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url

Node.js

認証コードをアクセス トークンと交換するには、getToken メソッドを使用します。

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
app.get('/oauth2callback', async (req, res) => {
  let q = url.parse(req.url, true).query;

  if (q.error) { // An error response e.g. error=access_denied
    console.log('Error:' + q.error);
  } else if (q.state !== req.session.state) { //check state value
    console.log('State mismatch. Possible CSRF attack');
    res.end('State mismatch. Possible CSRF attack');
  } else { // Get access and refresh tokens (if access_type is offline)

    let { tokens } = await oauth2Client.getToken(q.code);
    oauth2Client.setCredentials(tokens);
});

HTTP/REST

認証コードをアクセス トークンと交換するには、https://oauth2.googleapis.com/token エンドポイントを呼び出して、次のパラメータを設定します。

フィールド
client_id Credentials pageから取得したクライアント ID。 API Console
client_secret Credentials pageから取得したクライアント シークレット。 API Console
code 最初のリクエストから返された認証コード。
grant_type OAuth 2.0 仕様で定義されているように、このフィールドの値は authorization_code に設定する必要があります。
redirect_uri 指定された client_id の API Console Credentials page にプロジェクト用にリストされているリダイレクト URI の 1 つ。

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

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

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

Google はこのリクエストに対して、有効期間の短いアクセス トークンと更新トークンを含む JSON オブジェクトを返します。更新トークンは、Google の承認サーバー��の最初のリクエスト���、アプリケーションが access_type パラメータを offline に設定した場合にのみ返されます。

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

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

次のスニペットは、レスポンスの例を示しています。

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/yt-analytics.readonly",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

エラー

アクセス トークンの認証コードを交換すると、想定されるレスポンスではなく、次のエラーが発生することがあります。一般的なエラーコードと推奨される解決策を以下に示します。

invalid_grant

指定された認証コードが無効であるか、形式が正しくありません。OAuth プロセスを再起動して新しいコードをリクエストし、もう一度ユーザーに同意を求めます。

Google API の呼び出し

PHP

次の手順で、アクセス トークンを使用して Google API を呼び出します。

  1. アクセス トークンを新しい Google\Client オブジェクトに適用する必要がある場合(アクセス トークンをユーザー セッションに保存した場合など)は、setAccessToken メソッドを使用します。
    $client->setAccessToken($access_token);
  2. 呼び出す API のサービス オブジェクトを作成します。サービス オブジェクトを作成するには、呼び出す API のコンストラ��タに承認済みの Google\Client オブジェクトを指定します。 たとえば、YouTube Analytics API を呼び出すには、次のようにします。
    $youtube = new Google_Service_YouTubeAnalytics($client);
  3. サービス オブジェクトによって提供されるインターフェースを使用して、API サービスにリクエストを送信します。 たとえば、認証されたユーザーのチャンネルの YouTube アナリティクス レポートを取得するには、次のようにします。
    $report = $youtube->reports->query('channel==MINE', '2016-05-01', '2016-06-30', 'views');

Python

アクセス トークンを取得した後、アプリケーシ���ンはそのトークンを使用して、特定のユーザー アカウントまたはサービス アカウントに代わって API リクエストを承認できます。ユーザー固有の認証情報を使用して、呼び出す API のサービス オブジェクトを作成し、そのオブジェクトを使用して承認済みの API リクエストを行います。

  1. 呼び出す API のサービス オブジェクトを作成します。サービス オブジェクトを作成するには、API の名前とバージョン、ユーザー認証情報を使用して、googleapiclient.discovery ライブラリの build メソッドを呼び出します。 たとえば、YouTube Analytics API のバージョン 1 を呼び出すには、次のようにします。
    from googleapiclient.discovery import build
    
    youtube = build('youtubeAnalytics', 'v1', credentials=credentials)
  2. サービス オブジェクトによって提供されるインターフェースを使用して、API サービスにリクエストを送信します。 たとえば、認証されたユーザーのチャンネルの YouTube アナリティクス レポートを取得するには、次のようにします。
    report = youtube.reports().query(ids='channel==MINE', start_date='2016-05-01', end_date='2016-06-30', metrics='views').execute()

Ruby

アクセス トークンを取得した後、アプリケーションはそのトークンを使用して、特定のユーザー アカウントまたはサービス アカウントに代わって API リクエストを行うことができます。ユーザー固有の認証情報を使用して、呼び出す API のサービス オブジェクトを作成し、そのオブジェクトを使用して承認済みの API リクエストを行います。

  1. 呼び出す API のサービス オブジェクトを作成します。 たとえば、YouTube Analytics API のバージョン 1 を呼び出すには、次のようにします。
    youtube = Google::Apis::YoutubeAnalyticsV1::YouTubeAnalyticsService.new
  2. サービスに対して認証情報を設定します。
    youtube.authorization = credentials
  3. サービス オブジェクトによって提供されるインターフェースを使用して、API サービスにリクエストを送信します。 たとえば、認証されたユーザーのチャンネルの YouTube アナリティクス レポートを取得するには、次のようにします。
    report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views')

また、メソッドに options パラメータを指定することで、メソッドごとに認可を指定することもできます。

report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views', options: { authorization: auth_client })

Node.js

アクセス トークンを取得して OAuth2 オブジェクトに設定し、そのオブジェクトを使用して Google API を呼び出します。アプリケーションはこのトークンを使用して、特定のユーザー アカウントまたはサービス アカウントに代わって API リクエストを承認できます。呼び出す API のサービス オブジェクトを作成します。

const { google } = require('googleapis');

// Example of using Google Drive API to list filenames in user's Drive.
const drive = google.drive('v3');
drive.files.list({
  auth: oauth2Client,
  pageSize: 10,
  fields: 'nextPageToken, files(id, name)',
}, (err1, res1) => {
  if (err1) return console.log('The API returned an error: ' + err1);
  const files = res1.data.files;
  if (files.length) {
    console.log('Files:');
    files.map((file) => {
      console.log(`${file.name} (${file.id})`);
    });
  } else {
    console.log('No files found.');
  }
});

HTTP/REST

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

YouTube Analytics API は、サービス アカウントのフローをサポートしていません。YouTube Reporting API は、複数の YouTube チャンネルを所有、管理する YouTube コンテンツ所有者(レコード レーベルや映画スタジオなど)専用のサービス アカウントをサポートしています。

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

HTTP GET の例

Authorization: Bearer HTTP ヘッダーを使用した reports.query エンドポイント(YouTube Analytics API)の呼び出しは次のようになります。独自のアクセス トークンを指定する必要があります。

GET /youtube/analytics/v1/reports?ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

access_token クエリ文字列パラメータを使用した、認証されたユーザーに対して同じ API の呼び出しの例を次に示します。

GET https://www.googleapis.com/youtube/analytics/v1/reports?access_token=access_token&ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views

curl の例

これらのコマンドは、curl コマンドライン アプリケーションを使用してテストできます。HTTP ヘッダー オプションを使用した例を次に示します(推奨)。

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/analytics/v1/reports?ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views

または、クエリ文字列パラメータ オプションを使用します。

curl https://www.googleapis.com/youtube/analytics/v1/reports?access_token=access_token&ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views

完全なサンプルコード

次の例では、ユーザーがアプリケーションに YouTube アナリティクス レポートの取得を許可した後、認証されたユーザーの YouTube チャンネルの視聴回数データを示す JSON 形式のオブジェクトを出力します。

PHP

この例を実行するには:

  1. API Consoleで、ローカルマシンの URL をリダイレクト URL のリストに追加します(たとえば、http://localhost:8080 を追加します)。
  2. 新しいディレクトリを作成し、そのディレクトリに移動します。例:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. Composer を使用して PHP 用の Google API ��ライアント ライブラリ���インストールします。
    composer require google/apiclient:^2.10
  4. 以下の内容でファイル index.phpoauth2callback.php を作成します。
  5. PHP を提供するように構成されたウェブサーバーでサンプルを実行します。PHP 5.6 以降を使用している場合は、PHP の組み込みテストウェブサーバー(
    php -S localhost:8080 ~/php-oauth2-example
    )を使用できます。

index.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfig('client_secrets.json');
$client->addScope(Google_Service_YouTubeAnalytics::YT_ANALYTICS_READONLY);

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $client->setAccessToken($_SESSION['access_token']);
  $youtube = new Google_Service_YouTubeAnalytics($client);
  $report = $youtube->reports->query('channel==MINE', '2016-05-01', '2016-06-30', 'views');
  echo json_encode($report);
} else {
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

oauth2callback.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfigFile('client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope(Google_Service_YouTubeAnalytics::YT_ANALYTICS_READONLY);

if (! isset($_GET['code'])) {
  // Generate and set state value
  $state = bin2hex(random_bytes(16));
  $client->setState($state);
  $_SESSION['state'] = $state;

  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
  // Check the state value
  if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) {
    die('State mismatch. Possible CSRF attack.');
  }
  $client->authenticate($_GET['code']);
  $_SESSION['access_token'] = $client->getAccessToken();
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

Python

この例では、Flask フレームワークを使用します。OAuth 2.0 フローをテストできるウェブ アプリケーションを http://localhost:8080 で実行します。この URL にアクセスすると、次の 4 つのリンクが表示されます。

  • API リクエストをテストする: このリンクは、サンプル API リクエストの実行を試みるページへのリンクです。必要に応じて認可フローを開始します。成功すると、ページに API レスポンスが表示されます。
  • 認証フローを直接テストする: このリンクは、認可フローを介してユーザーを送信しようとするページへのリンクです。アプリは、ユーザーに代わって承認済みの API リクエストを送信する権限をリクエストします。
  • 現在の認証情報を取り消す: ユーザーがすでにアプリケーションに付与している権限を 取り消すページへのリンクです。
  • Flask セッション認証情報の消去: このリンクから、Flask セッションに保存されている認証情報を消去します。これにより、すでにアプリに権限を付与しているユーザーが新しいセッションで API リクエストを実行しようとした場合にどうなるかがわかります。また、ユーザーがアプリに付与されている権限を取り消した後でも、アプリが取り消されたアクセス トークンでリクエストの承認を試みた場合に、アプリが受け取る API レスポンスも確認できます。
# -*- coding: utf-8 -*-

import os
import flask
import requests

import google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery

# This variable specifies the name of a file that contains the OAuth 2.0
# information for this application, including its client_id and client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/yt-analytics.readonly']
API_SERVICE_NAME = 'youtubeAnalytics'
API_VERSION = 'v1'

app = flask.Flask(__name__)
# Note: A secret key is included in the sample so that it works.
# If you use this code in your application, replace this with a truly secret
# key. See https://flask.palletsprojects.com/quickstart/#sessions.
app.secret_key = 'REPLACE ME - this value is here as a placeholder.'


@app.route('/')
def index():
  return print_index_table()


@app.route('/test')
def test_api_request():
  if 'credentials' not in flask.session:
    return flask.redirect('authorize')

  # Load credentials from the session.
  credentials = google.oauth2.credentials.Credentials(
      **flask.session['credentials'])

  youtube = googleapiclient.discovery.build(
      API_SERVICE_NAME, API_VERSION, credentials=credentials)

  report = youtube.reports().query(ids='channel==MINE', start_date='2016-05-01', end_date='2016-06-30', metrics='views').execute()

  # Save credentials back to session in case access token was refreshed.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.jsonify(**report)


@app.route('/authorize')
def authorize():
  # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES)

  # The URI created here must exactly match one of the authorized redirect URIs
  # for the OAuth 2.0 client, which you configured in the API Console. If this
  # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
  # error.
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  authorization_url, state = flow.authorization_url(
      # Enable offline access so that you can refresh an access token without
      # re-prompting the user for permission. Recommended for web server apps.
      access_type='offline',
      # Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes='true')

  # Store the state so the callback can verify the auth server response.
  flask.session['state'] = state

  return flask.redirect(authorization_url)


@app.route('/oauth2callback')
def oauth2callback():
  # Specify the state when creating the flow in the callback so that it can
  # verified in the authorization server response.
  state = flask.session['state']

  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  # Use the authorization server's response to fetch the OAuth 2.0 tokens.
  authorization_response = flask.request.url
  flow.fetch_token(authorization_response=authorization_response)

  # Store credentials in the session.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  credentials = flow.credentials
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.redirect(flask.url_for('test_api_request'))


@app.route('/revoke')
def revoke():
  if 'credentials' not in flask.session:
    return ('You need to <a href="/authorize">authorize</a> before ' +
            'testing the code to revoke credentials.')

  credentials = google.oauth2.credentials.Credentials(
    **flask.session['credentials'])

  revoke = requests.post('https://oauth2.googleapis.com/revoke',
      params={'token': credentials.token},
      headers = {'content-type': 'application/x-www-form-urlencoded'})

  status_code = getattr(revoke, 'status_code')
  if status_code == 200:
    return('Credentials successfully revoked.' + print_index_table())
  else:
    return('An error occurred.' + print_index_table())


@app.route('/clear')
def clear_credentials():
  if 'credentials' in flask.session:
    del flask.session['credentials']
  return ('Credentials have been cleared.<br><br>' +
          print_index_table())


def credentials_to_dict(credentials):
  return {'token': credentials.token,
          'refresh_token': credentials.refresh_token,
          'token_uri': credentials.token_uri,
          'client_id': credentials.client_id,
          'client_secret': credentials.client_secret,
          'scopes': credentials.scopes}

def print_index_table():
  return ('<table>' +
          '<tr><td><a href="/test">Test an API request</a></td>' +
          '<td>Submit an API request and see a formatted JSON response. ' +
          '    Go through the authorization flow if there are no stored ' +
          '    credentials for the user.</td></tr>' +
          '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
          '<td>Go directly to the authorization flow. If there are stored ' +
          '    credentials, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' +
          '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
          '<td>Revoke the access token associated with the current user ' +
          '    session. After revoking credentials, if you go to the test ' +
          '    page, you should see an <code>invalid_grant</code> error.' +
          '</td></tr>' +
          '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
          '<td>Clear the access token currently stored in the user session. ' +
          '    After clearing the token, if you <a href="/test">test the ' +
          '    API request</a> again, you should go back to the auth flow.' +
          '</td></tr></table>')


if __name__ == '__main__':
  # When running locally, disable OAuthlib's HTTPs verification.
  # ACTION ITEM for developers:
  #     When running in production *do not* leave this option enabled.
  os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

  # Specify a hostname and port that are set as a valid redirect URI
  # for your API project in the Google API Console.
  app.run('localhost', 8080, debug=True)

Ruby

この例では、Sinatra ��レームワークを使用します。

require 'google/apis/youtube_analytics_v1'
require 'sinatra'
require 'googleauth'
require 'googleauth/stores/redis_token_store'

configure do
  enable :sessions

  set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')
  set :scope, Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY
  set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
  set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, '/oauth2callback')
end

get '/' do
  user_id = settings.client_id.id
  credentials = settings.authorizer.get_credentials(user_id, request)
  if credentials.nil?
    redirect settings.authorizer.get_authorization_url(login_hint: user_id, request: request)
  end
  youtube = Google::Apis::YoutubeAnalyticsV1::YouTubeAnalyticsService.new
  report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views', options: { authorization: auth_client })
  
  "<pre>#{JSON.pretty_generate(report.to_h)}</pre>"
end

get '/oauth2callback' do
  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url
end

Node.js

この例を実行するには:

  1. API Consoleで、ローカルマシンの URL をリダイレクト URL のリストに追加します(たとえば、http://localhost を追加します)。
  2. メンテナンス LTS、アクティブな LTS、または Node.js の現在のリリースがインストールされていることを確認します。
  3. 新しいディレクトリを作成し、そのディレクトリに移動します。次に例を示します。
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. Install the Google API Client Library for Node.js using npm:
    npm install googleapis
  5. 以下の内容でファイル main.js を作成します。
  6. サンプルを実行します。
    node .\main.js

main.js

const http = require('http');
const https = require('https');
const url = require('url');
const { google } = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
 * To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];
/* Global variable that stores user credential in this code example.
 * ACTION ITEM for developers:
 *   Store user's refresh token in your data store if
 *   incorporating this code into your real app.
 *   For more information on handling refresh tokens,
 *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
 */
let userCredential = null;

async function main() {
  const app = express();

  app.use(session({
    secret: 'your_secure_secret_key', // Replace with a strong secret
    resave: false,
    saveUninitialized: false,
  }));

  // Example on redirecting user to Google's OAuth 2.0 server.
  app.get('/', async (req, res) => {
    // Generate a secure random state value.
    const state = crypto.randomBytes(32).toString('hex');
    // Store state in the session
    req.session.state = state;

    // Generate a url that asks permissions for the Drive activity scope
    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true,
      // Include the state parameter to reduce the risk of CSRF attacks.
      state: state
    });

    res.redirect(authorizationUrl);
  });

  // Receive the callback from Google's OAuth 2.0 server.
  app.get('/oauth2callback', async (req, res) => {
    // Handle the OAuth 2.0 server response
    let q = url.parse(req.url, true).query;

    if (q.error) { // An error response e.g. error=access_denied
      console.log('Error:' + q.error);
    } else if (q.state !== req.session.state) { //check state value
      console.log('State mismatch. Possible CSRF attack');
      res.end('State mismatch. Possible CSRF attack');
    } else { // Get access and refresh tokens (if access_type is offline)
      let { tokens } = await oauth2Client.getToken(q.code);
      oauth2Client.setCredentials(tokens);

      /** Save credential to the global variable in case access token was refreshed.
        * ACTION ITEM: In a production app, you likely want to save the refresh token
        *              in a secure persistent database instead. */
      userCredential = tokens;

      // Example of using Google Drive API to list filenames in user's Drive.
      const drive = google.drive('v3');
      drive.files.list({
        auth: oauth2Client,
        pageSize: 10,
        fields: 'nextPageToken, files(id, name)',
      }, (err1, res1) => {
        if (err1) return console.log('The API returned an error: ' + err1);
        const files = res1.data.files;
        if (files.length) {
          console.log('Files:');
          files.map((file) => {
            console.log(`${file.name} (${file.id})`);
          });
        } else {
          console.log('No files found.');
        }
      });
    }
  });

  // Example on revoking a token
  app.get('/revoke', async (req, res) => {
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;

    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };

    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });

    postReq.on('error', error => {
      console.log(error)
    });

    // Post the request with data
    postReq.write(postData);
    postReq.end();
  });


  const server = http.createServer(app);
  server.listen(80);
}
main().catch(console.error);

HTTP/REST

この Python の例では、Flask フレームワークと Requests ライブラリを使用して、OAuth 2.0 ウェブフローを示します。このフローでは、Python 用 Google API クライアント ライブラリを使用することをおすすめします。([Python] タブの例では、クライアント ライブラリを使用しています)。

import json

import flask
import requests


app = flask.Flask(__name__)

CLIENT_ID = '123456789.apps.googleusercontent.com'
CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app
SCOPE = 'https://www.googleapis.com/auth/yt-analytics.readonly'
REDIRECT_URI = 'http://example.com/oauth2callback'


@app.route('/')
def index():
  if 'credentials' not in flask.session:
    return flask.redirect(flask.url_for('oauth2callback'))
  credentials = json.loads(flask.session['credentials'])
  if credentials['expires_in'] <= 0:
    return flask.redirect(flask.url_for('oauth2callback'))
  else:
    headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
    req_uri = 'https://www.googleapis.com/youtube/analytics/v1/reports'
    r = requests.get(req_uri, headers=headers)
    return r.text


@app.route('/oauth2callback')
def oauth2callback():
  if 'code' not in flask.request.args:
    state = str(uuid.uuid4())
    flask.session['state'] = state
    auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI,
                                                                          SCOPE, state)
    return flask.redirect(auth_uri)
  else:
    if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']:
      return 'State mismatch. Possible CSRF attack.', 400

    auth_code = flask.request.args.get('code')
    data = {'code': auth_code,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI,
            'grant_type': 'authorization_code'}
    r = requests.post('https://oauth2.googleapis.com/token', data=data)
    flask.session['credentials'] = r.text
    return flask.redirect(flask.url_for('index'))


if __name__ == '__main__':
  import uuid
  app.secret_key = str(uuid.uuid4())
  app.debug = False
  app.run()

リダイレクト URI の検証ルール

Google では、デベロッパーがアプリを安全に保つために、リダイレクト URI に次の検証ルールを適用しています。リダイレクト URI は、これらのルールに従う必要があります。下記の domain、host、path、query、scheme、userinfo の定義については、RFC 3986 のセクション 3 をご覧ください。

検証ルール
スキーム

リダイレクト URI には、通常の HTTP ではなく HTTPS スキームを使用する必要があります。ローカルホスト URI(localhost IP アドレス URI を含む)は、このルールから除外されます。

ホスト

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

ドメイン
  • ホスト TLD(トップレベル ドメイン)は、パブリック サフィックス リストに属している必要があります。
  • ホストドメインを “googleusercontent.com” にすることはできません。
  • アプリがドメインを所有���ている場合を除き、リダイレクト URI に短縮 URL のドメイン(goo.gl など)を含めることはできません。さらに、短縮ドメインを所有するアプリがそのドメインにリダイレクトする場合、そのリダイレクト URI のパスに “/google-callback/” を含めるか、末尾を “/google-callback” にする必要があります。
  • ユーザー情報

    リダイレクト URI に userinfo サブコンポーネントを含めることはできません。

    [パス]

    リダイレクト URI には、“/..”“\..”、またはその URL エンコードで表されるパス トラバーサル(ディレクトリ バックトラッキングとも呼ばれます)を含めることはできません。

    Query

    リダイレクト URI にオープン リダイレクトを含めることはできません。

    Fragment

    リダイレクト URI にフラグメント コンポーネントを含めることはできません。

    文字数 リダイレクト URI には、次のような特定の文字を含めることはできません。
    • ワイルドカード文字('*'
    • 印刷できない ASCII 文字
    • 無効なパーセント エンコード(パーセント記号の後に 2 桁の 16 進数が続く URL エンコード形式に準拠していないパーセント エンコーディング)
    • null 文字(エンコードされた NULL 文字(例:%00%C0%80

    段階的な認可

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

    たとえば、アプリが YouTube アナリティクス レポートを取得するとします。その一部は収益レポートであり、他のレポートには不要なスコープへのアクセスが必要です。この場合、アプリはログイン時に https://www.googleapis.com/auth/yt-analytics.readonly スコープへのアクセスのみをリクエストする可能性があります。ただし、ユーザーが売上レポートを取得しようとした場合、アプリは https://www.googleapis.com/auth/yt-analytics-monetary.readonly スコープへのアクセスをリクエストすることもできます。

    増分認可を実装するには、アクセス トークンをリクエストする通常のフローを完了しますが、以前に付与されたスコープが認可リクエストに含まれていることを確認します。このアプローチによ��、アプリは複数のアクセス トークンを管理する必要がなくなります。

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

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

    ステップ 1: 認証パラメータを設定するの言語固有のコードサンプルとステップ 2: Google の OAuth 2.0 サーバーへのリダイレクトのサンプル HTTP/REST リダイレクト URL では、すべて増分認証を使用します。以下のコードサンプルには、増分認証を使用するために追加する必要があるコードも示しています。

    PHP

    $client->setIncludeGrantedScopes(true);

    Python

    Python では、include_granted_scopes キーワード引数を true に設定して、以前に付与されたスコープが認可リクエストに含まれるようにします。以下の例に示すように、設定するキーワード引数が include_granted_scopes だけではない場合もあります。

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    Ruby

    auth_client.update!(
      :additional_parameters => {"include_granted_scopes" => "true"}
    )

    Node.js

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });
    

    HTTP/REST

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

    GET https://accounts.google.com/o/oauth2/v2/auth?
      scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly&
      access_type=offline&
      state=security_token%3D138rk%3Btarget_url%3Dhttp...index&
      redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
      response_type=code&
      client_id=client_id&
      include_granted_scopes=true
    
          

    Refreshing an access token (offline access)

    Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.

    • If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
    • If you are not using a client library, you need to set the access_type HTTP query parameter to offline when redirecting the user to Google's OAuth 2.0 server. In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.

    Requesting offline access is a requirement for any application that needs to access a Google API when the user is not present. For example, an app that performs backup services or executes actions at predetermined times needs to be able to refresh its access token when the user is not present. The default style of access is called online.

    Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.

    PHP

    If your application needs offline access to a Google API, set the API client's access type to offline:

    $client->setAccessType("offline");

    ユーザーがリクエストしたスコープへのオフライン アクセスを許可した後も、ユーザーがオフラインのときは引き続き API クライアントを使用して、ユーザーに代わって Google API にアクセスできます。クライアント オブジェクトは、必要に応じてアクセス トークンを更新します。

    Python

    Python では、access_type キーワード引数を offline に設定して、ユーザーに権限を再度要求することなくアクセス トークンを更新できるようにします。以下の例に示すように、設定するキーワード引数が access_type だけではない場合もあります。

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    ユーザーがリクエストしたスコープへのオフライン アクセスを許可した後も、ユーザーがオフラインのときは引き続き API クライアントを使用して、ユーザーに代わって Google API にアクセスできます。クライアン��� オブジェクトは、必要に応じてアクセス トークンを更新します。

    Ruby

    アプリケーションで Google API にオフラインでアクセスする必要がある場合は、API クライアントのアクセスタイプを offline に設定します。

    auth_client.update!(
      :additional_parameters => {"access_type" => "offline"}
    )

    ユーザーがリクエストしたスコープへのオフライン アクセスを許可した後も、ユーザーがオフラインのときは引き続き API クライアントを使用して、ユーザーに代わって Google API にアクセスできます。クライアント オブジェクトは、必要に応じてアクセス トークンを更新します。

    Node.js

    アプリケーションで Google API にオフラインでアクセスする必要がある場合は、API クライアントのアクセスタイプを offline に設定します。

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });
    

    ユーザーがリクエストしたスコープへのオフライン アクセスを許可した後も、ユーザーがオフラインのときは引き続き API クライアントを使用して、ユーザーに代わって Google API にアクセスできます。クライアント オブジェクトは、必要に応じてアクセス トークンを更新します。

    アクセス トークンには有効期限があります。このライブラリは、アクセス トークンの有効期限が近づいている場合、自動的に更新トークンを使用して新しいアクセス トークンを取得します。常に最新のトークンを格納する簡単な方法は、トークン イベントを使用することです。

    oauth2Client.on('tokens', (tokens) => {
      if (tokens.refresh_token) {
        // store the refresh_token in your secure persistent database
        console.log(tokens.refresh_token);
      }
      console.log(tokens.access_token);
    });

    このトークン イベントは最初の認証でのみ発生します。更新トークンを取得するには、generateAuthUrl メソッドを呼び出すときに access_typeoffline に設定する必要があります。更新トークンを受け取るための適切な制約を設定せずに、すでにアプリに必要な権限を付与している場合は、新しい更新トークンを受け取るためにアプリを再承認する必要があります。

    後で refresh_token を設定するには、setCredentials メソッドを使用します。

    oauth2Client.setCredentials({
      refresh_token: `STORED_REFRESH_TOKEN`
    });
    

    クライアントが更新トークンを取得すると、次の API 呼び出しでアクセス トークンが取得され、自動的に更新されます。

    HTTP/REST

    アクセス トークンを更新するため、次のパラメータを含む 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 つの上限があります。更新トークンは長期保存に保管し、有効な間は使用し続ける必要があります。アプリケーションがあまりにも多くの更新トークンをリクエストすると、これらの上限に���する可能性があります。その場合、古い更新トークンは機能しなくなります。

    トークンの取り消し

    アプリケーションに付与したアクセス権の取り消しをユーザーが希望する場合があります。ユーザーは [ アカウント設定] にアクセスしてアクセス権を取り消すことができます。詳しくは、サポート ドキュメントの「アカウントにアクセスできるサードパーティのサイトやアプリ」の「サイトまたはアプリのアクセス権を削除する」をご覧ください。

    また、アプリケーションに付与されているアクセス権をプログラムで取り消すこともできます。プログラムによる取り消しは、ユーザーが登録解除した場合や、アプリケーションを削除した場合、またはアプリが必要とする API リソースが大幅に変更された場合に重要です。つまり、削除プロセスの一部に API リクエストを含めて、アプリに以前付与された権限を確実に削除することができます。

    PHP

    プログラムでトークンを取り消すには、revokeToken() を呼び出します。

    $client->revokeToken();

    Python

    プログラムでトークンを取り消すには、トークンをパラメータとして含み、Content-Type ヘッダーを設定する https://oauth2.googleapis.com/revoke に対してリクエストを行います。

    requests.post('https://oauth2.googleapis.com/revoke',
        params={'token': credentials.token},
        headers = {'content-type': 'application/x-www-form-urlencoded'})

    Ruby

    プログラムでトークンを取り消すには、oauth2.revoke エンドポイントに HTTP リクエストを送信します。

    uri = URI('https://oauth2.googleapis.com/revoke')
    response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
    

    トークンは、アクセス トークンまたはリフレッシュ トークンです。トークンがアクセス トークンであり、対応する更新トークンがある場合、更新トークンも取り消されます。

    取り消しが正常に処理された場合、レスポンスのステータス コードは 200 です。エラー状態の場合、ステータス コード 400 がエラーコードとともに返されます。

    Node.js

    プログラムでトークンを取り消すには、/revoke エンドポイントに対して HTTPS POST リクエストを行います。

    const https = require('https');
    
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;
    
    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };
    
    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });
    
    postReq.on('error', error => {
      console.log(error)
    });
    
    // Post the request with data
    postReq.write(postData);
    postReq.end();
    

    トークン パラメータには、アクセス トークンまたはリフレッシュ トークンを指定できます。トークンがアクセス トークンであり、対応する更新トークンがある場合、更新トークンも取り消されます。

    取り消しが正常に処理された場合、レスポンスのステータス コードは 200 です。エラー状態の場合、ステータス コード 400 がエラーコードとともに返されます。

    HTTP/REST

    プログラムでトークンを取り消すには、アプリケーションで 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 がエラーコードとともに返されます。