OpenID Connect

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

Google の OAuth 2.0 API は、認証と認可の両方に使用できます。このドキュメントは、OpenID Connect 仕様に準拠し、OpenID Certified として認証を行うための OAuth 2.0 の実装について説明しています。このサービスは、OAuth 2.0 を使用して Google API にアクセスするにあるドキュメントにも当てはまります。このプロトコルをインタラクティブに調べたい場合は、Google OAuth 2.0 Playground をおすすめします。Stack Overflow のヘルプを利用するには、質問に 'google-oauth' のタグを付けてください。

OAuth 2.0 の設定

アプリケーションでユーザーのログインに Google の OAuth 2.0 認証システムを使用する前に、 Google API Console でプロジェクトを設定し、OAuth 2.0 認証情報を取得してリダイレクト URI を設定し、必要に応じて、ユーザーの同意画面でユーザーに表示されるブランディング情報をカスタマイズします。また、 API Console を使用して、サービス アカウントの作成、課金の有効化、フィルタの設定などのタスクを行うこともできます。詳細については、Google API Consoleヘルプをご覧ください。

OAuth 2.0 認証情報を取得する

ユーザーを認証して Google の API にアクセスするには、クライアント ID とクライアント シークレットを含む OAuth 2.0 認証情報が必要です。

特定のOAuth 2.0認証情報のクライアントIDとクライアントシークレットを表示するには、次のテキストをクリックします認証情報を選択 。開いたウィンドウで、プロジェクトと必要な認証情報を選択し、[ 表示 ]をクリックします

または、 API Console [ 認証情報]ページからクライアントIDとクライアントシークレットを表示しAPI Console 。

  1. Go to the Credentials page.
  2. 資格情報の名前または鉛筆( )アイコンをクリックします。クライアントIDとシークレットはページの上部にあります。

リダイレクト URI を設定する

API Console で設定したリダイレクト URI によって、Google が認証リクエストにレスポンスを送信する場所が決まります。

To create, view, or edit the redirect URIs for a given OAuth 2.0 credential, do the following:

  1. Go to the Credentials page.
  2. In the OAuth 2.0 client IDs section of the page, click a credential.
  3. View or edit the redirect URIs.

If there is no OAuth 2.0 client IDs section on the Credentials page, then your project has no OAuth credentials. To create one, click Create credentials.

ユーザーの同意画面をカスタマイズする

ユーザーのために、OAuth 2.0 認証エクスペリエンスには、ユーザーがリリースする情報と適用される規約を説明する同意画面が含まれています。たとえば、ユーザーがログインすると、アプリにメールアドレスと基本的なアカウント情報へのアクセスを許可するよう求められることがあります。この情報へのアクセス権をリクエストするには、scope パラメータを使用します。このパラメータは、アプリの認証リクエストに含まれます。スコープを使用して、他の Google API へのアクセスをリクエストすることもできます。

ユーザーの同意画面には、商品名、ロゴ、ホームページの URL などのブランディング情報も表示されます。ブランディング情報は API Consoleで管理できます。

To enable your project's consent screen:

  1. Open the Consent Screen page in the Google API Console.
  2. If prompted, select a project, or create a new one.
  3. Fill out the form and click Save.

次の同意ダイアログは、リクエストに OAuth 2.0 と Google ドライブのスコープが混在している場合にユーザーに表示される内容を示しています。(この汎用ダイアログは Google OAuth 2.0 Playground を使用して生成されたため、 API Consoleで設定されるブランディング情報は含まれません)。

同意ページのスクリーンショット

サービスへのアクセス

Google とサードパーティが提供するライブラリを使用すると、ユーザーの認証や Google API へのアクセス権の取得など、実装の詳細の多くを処理できます。例としては、Google Identity ServicesGoogle クライアント ライブラリがあり、これらはさまざまなプラットフォームで利用できます。

ライブラリを使用しない場合は、このドキュメントの残りの部分で、利用可能なライブラリの基礎となる HTTP リクエスト フローについて説明します。

ユーザーの認証

ユーザーの認証には、ID トークンの取得と検証が必要です。ID トークンは、OpenID Connect の標準機能であり、インターネット上の ID アサーションの共有に使用されます。

ユーザーを認証して ID トークンを取得する最も一般的なアプローチは、「サーバー」フローと「暗黙的」フローです。サーバー フローにより、アプリケーションのバックエンド サーバーは、ブラウザまたはモバイル デバイスを使用してユーザーの本人確認を行うことができます。暗黙的フローは、クライアント側アプリケーション(通常はブラウザで実行されている JavaScript アプリ)がバックエンド サーバー経由でではなく、API に直接アクセスする必要がある場合に使用されます。

このドキュメントでは、ユーザーを認証するためのサーバーフローを実行する方法について説明します。クライアント側でトークンを処理して使用すると、セキュリティ上のリスクがあるため、暗黙的フローは非常に複雑になります。暗黙的フローを実装する必要がある場合は、Google Identity Services を使用することを強くおすすめします。

サーバーフロー

これらのプロトコルを使用してユーザーを認証できるように、 API Consoleでアプリを設定してください。ユーザーが Google でログインしようとした場合:

  1. 偽造防止状態トークンを作成する
  2. Google に認証リクエストを送信する
  3. 偽造防止状態トークンを確認する
  4. code をアクセス トークンと ID トークンに交換
  5. ID トークンからユーザー情報を取得する
  6. ユーザーを認証する

1. 偽造防止状態トークンを作成する

リクエスト フォージェリ攻撃を防ぐことで、ユーザーのセキュリティを保護する必要があります。まず、アプリとユーザーのクライアントとの間で状態を保持する一意のセッション トークンを作成します。 その後、この一意のセッション トークンを Google OAuth ログイン サービスから返された認証レスポンスと照合して、ユーザーが悪意のあるリクエストではなく、リクエストを行っていることを確認します。これらのトークンは通常、クロスサイト リクエスト フォージェリ(CSRF)トークンと呼ばれます。

状態トークンには、高品質な乱数ジェネレータを使用して 30 文字程度の文字列を作成することをおすすめします。もう 1 つは、バックエンドでシークレットが保持されている鍵を使用してセッション状態変数の一部に署名することで生成されるハッシュです。

次のコードは、一意のセッション トークンを生成する方法を示しています。

PHP

このサンプルを使用するには、PHP 用 Google API クライアント ライブラリをダウンロードする必要があります。

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
$state = bin2hex(random_bytes(128/8));
$app['session']->set('state', $state);
// Set the client ID, token state, and application name in the HTML while
// serving it.
return $app['twig']->render('index.html', array(
    'CLIENT_ID' => CLIENT_ID,
    'STATE' => $state,
    'APPLICATION_NAME' => APPLICATION_NAME
));

Java

このサンプルを使用するには、Java 用 Google API クライアント ライブラリをダウンロードする必要があります。

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
String state = new BigInteger(130, new SecureRandom()).toString(32);
request.session().attribute("state", state);
// Read index.html into memory, and set the client ID,
// token state, and application name in the HTML before serving it.
return new Scanner(new File("index.html"), "UTF-8")
    .useDelimiter("\\A").next()
    .replaceAll("[{]{2}\\s*CLIENT_ID\\s*[}]{2}", CLIENT_ID)
    .replaceAll("[{]{2}\\s*STATE\\s*[}]{2}", state)
    .replaceAll("[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}",
    APPLICATION_NAME);

Python

このサンプルを使用するには、Python 用 Google API クライアント ライブラリをダウンロードする必要があります。

# Create a state token to prevent request forgery.
# Store it in the session for later validation.
state = hashlib.sha256(os.urandom(1024)).hexdigest()
session['state'] = state
# Set the client ID, token state, and application name in the HTML while
# serving it.
response = make_response(
    render_template('index.html',
                    CLIENT_ID=CLIENT_ID,
                    STATE=state,
                    APPLICATION_NAME=APPLICATION_NAME))

2. Google に認証リクエストを送信する

次のステップでは、適切な URI パラメータを指定して HTTPS GET リクエストを作成します。このプロセスのすべてのステップで、HTTP ではなく HTTPS を使用することに注意してください。HTTP 接続は拒否されます。authorization_endpoint メタデータ値を使用して、ディスカバリ ドキュメントからベース URI を取得する必要があります。以下の説明では、ベース URI は https://accounts.google.com/o/oauth2/v2/auth であることを前提としています。

基本的なリクエストでは、次のパラメータを指定します。

  • client_id。 API ConsoleCredentials pageから取得します。
  • response_type。基本認証コードフローのリクエストでは code になります。(詳しくは、response_type をご覧ください)。
  • scope。基本的なリクエストでは openid email になります。(詳しくは、scope をご覧ください)。
  • redirect_uri は、Google からのレスポンスを受信するサーバーの HTTP エンドポイントである必要があります。この値は、 Credentials pageで構成した OAuth 2.0 クライアントの承認済みのリダイレクト URI のいずれかと正確に一致している必要があります。 API Consoleこの値が承認済みの URI と一致しない場合、リクエストは失敗し、redirect_uri_mismatch エラーが発生します。
  • state には、アンチ フォージェリ防止の一意のセッション トークンの値と、ユーザーがアプリケーションに戻ったときにコンテキストを復元するために必要なその他の情報(開始 URL など)を含めます。 (詳しくは、state をご覧ください)。
  • nonce は、アプリによって生成されたランダムな値であり、存在する場合にリプレイ保護を有効にします。
  • login_hint には、ユーザーのメールアドレスまたは sub 文字列(ユーザーの Google ID と同等のもの)を使用できます。login_hint を提供せず、ユーザーが現在ログインしている場合、同意画面にユーザーのメールアドレスをアプリに解放するための承認リクエストが表示されます(詳しくは、login_hint をご覧ください)。
  • hd パラメータを使用して、Google Cloud 組織に関連付けられている特定のドメインのユーザーに対する OpenID Connect フローを最適化します。(詳しくは、hd をご覧ください)。

以下に、完全な OpenID Connect 認証 URI の例を示します。読みやすくするために、改行とスペースが含まれています。

https://accounts.google.com/o/oauth2/v2/auth?
 response_type=code&
 client_id=424911365001.apps.googleusercontent.com&
 scope=openid%20email&
 redirect_uri=https%3A//oauth2.example.com/code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2-login-demo.example.com%2FmyHome&
 login_hint=jsmith@example.com&
 nonce=0394852-3190485-2490358&
 hd=example.com

アプリがユーザーに新しい情報をリクエストしている場合、またはユーザーが以前に承認していないアカウントへのアクセスをアプリがリクエストする場合は、ユーザーの同意を求める必要があります。

3. 偽造防止状態トークンを確認する

レスポンスは、リクエストで指定した redirect_uri に送信されます。次に示すように、すべてのレスポンスがクエリ文字列で返されます。

https://oauth2.example.com/code?state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foa2cb.example.com%2FmyHome&code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&scope=openid%20email%20https://www.googleapis.com/auth/userinfo.email

サーバーで、Google から受け取った stateステップ 1 で作成したセッション トークンと一致していることを確認する必要があります。このラウンドトリップ検証により、ユーザーが悪意のあるスクリプトではなく、確実にリクエストを行っているかを確認できます。

次のコードは、手順 1 で作成したセッション トークンを確認する方法を示しています。

PHP

このサンプルを使用するには、PHP 用 Google API クライアント ライブラリをダウンロードする必要があります。

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if ($request->get('state') != ($app['session']->get('state'))) {
  return new Response('Invalid state parameter', 401);
}

Java

このサンプルを使用するには、Java 用 Google API クライアント ライブラリをダウンロードする必要があります。

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if (!request.queryParams("state").equals(
    request.session().attribute("state"))) {
  response.status(401);
  return GSON.toJson("Invalid state parameter.");
}

Python

このサンプルを使用するには、Python 用 Google API クライアント ライブラリをダウンロードする必要があります。

# Ensure that the request is not a forgery and that the user sending
# this connect request is the expected user.
if request.args.get('state', '') != session['state']:
  response = make_response(json.dumps('Invalid state parameter.'), 401)
  response.headers['Content-Type'] = 'application/json'
  return response

4. code をアクセス トークンと ID トークンに交換します

レスポンスには code パラメータが含まれます。これは、サーバーがアクセス トークンや ID トークンと交換できる 1 回限りの認証コードです。サーバーはこの交換を行うために、HTTPS POST リクエストを送信します。POST リクエストがトークン エンドポイントに送信されます。トークンは、ディスカバリ ドキュメントから token_endpoint メタデータ値を使用して取得する必要があります。以下の説明では、エンドポイントは https://oauth2.googleapis.com/token であることを前提としています。リクエストの POST 本文に次のパラメータを含める必要があります。

フィールド
code 最初のリクエストから返される認証コード。
client_id API ConsoleCredentials pageから取得するクライアント ID。OAuth 2.0 認証情報を取得する をご覧ください。
client_secret OAuth 2.0 認証情報を取得するに記載されているように、 API ConsoleCredentials pageから取得したクライアント シークレット。
redirect_uri API ConsoleCredentials pageで指定された特定の client_id の承認済みリダイレクト URI。リダイレクト URI を設定するをご覧ください。
grant_type このフィールドには OAuth 2.0 仕様で定義されているようにauthorization_code の値が含まれている必要があります。

実際のリクエストは次のようになります。

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

このリクエストへのレスポンスが成功すると、JSON 配列に次のフィールドが含まれます。

フィールド
access_token Google API に送信できるトークン。
expires_in アクセス トークンの残りの有効期間(秒単位)。
id_token Google によってデジタル署名されたユーザーの ID 情報を含む JWT
scope access_token で付与されるアクセス スコープ。スペースで区切る大文字と小文字の区別のある文字列のリストとして表現されます。
token_type 返されるトークンのタイプを示します。現時点では、このフィールドの値は常に Bearer です。
refresh_token (省略可)

このフィールドは、認証リクエストaccess_type パラメータが offline に設定された場合にのみ存在します。 詳しくは、更新トークンをご覧ください。

5. ID トークンからユーザー情報を取得する

ID トークンは、JWT(JSON Web Token)です。つまり、暗号的に署名された Base64 でエンコードされた JSON オブジェクトです。通常は、使用する前に ID トークンを検証することが重要です。ただし、中間無料 HTTPS チャネルを介して Google と直接通信し、クライアント シークレットを使用して Google に対して認証を行うと、受信するトークンは本当に Google からのものであり、有効です。サーバーがこの ID トークンをアプリの他のコンポーネントに渡す場合、他のコンポーネントが使用する前にそのトークンを検証することが非常に重要です。

ほとんどの API ライブラリでは、base64url エンコードされた値をデコードし、その内部で JSON を解析する作業と検証が組み合わされているため、ID トークン内のクレームにアクセスすると必ずトークンが検証されることになります。

ID トークンのペイロード

ID トークンは、名前と値のペアのセットを含む JSON オブジェクトです。以下に、読みやすい形式で例を示します。

{
  "iss": "https://accounts.google.com",
  "azp": "1234987819200.apps.googleusercontent.com",
  "aud": "1234987819200.apps.googleusercontent.com",
  "sub": "10769150350006150715113082367",
  "at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q",
  "hd": "example.com",
  "email": "jsmith@example.com",
  "email_verified": "true",
  "iat": 1353601026,
  "exp": 1353604926,
  "nonce": "0394852-3190485-2490358"
}

Google ID トークンには、次のフィールド(クレーム)を含めることができます。

請求 指定のクレジット カード 説明
aud 常に この ID トークンの対象ユーザー。アプリケーションの OAuth 2.0 クライアント ID のいずれかにする必要があります。
exp 常に ID トークンの有効期限である有効期限。Unix 時間(整数秒)で表されます。
iat 常に ID トークンが発行された時刻。Unix 時間(整数秒)で表されます。
iss 常に レスポンスの発行者の発行者 ID。Google ID トークンの場合は、常に https://accounts.google.com または accounts.google.com です。
sub 常に ユーザーの ID。すべての Google アカウントで一意であり、再利用されることはありません。Google アカウントでは、複数の時点において複数のメールアドレスを設定できますが、sub 値が変更されることはありません。アプリケーション内で、sub をユーザーの一意の識別子キーとして使用します。最大 255 文字(大文字と小文字を区別する ASCII 文字)。
at_hash アクセス トークンのハッシュ。アクセス トークンが ID トークンに関連付けられていることが検証されます。サーバーフローで ID トークンが access_token 値を使用して発行されている場合、このクレームは常に含まれます。このクレームは、クロスサイト リクエスト フォージェリ攻撃から保護するための代替メカニズムとして使用できますが、ステップ 1ステップ 3 に従っている場合、アクセス トークンを検証する必要はありません。
azp 承認されたプレゼンターの client_id。このクレームは、ID トークンをリクエストする当事者が ID トークンのオーディエンスと異なる場合にのみ必要です。Google のハイブリッド アプリでは、ウェブアプリと Android アプリの OAuth 2.0 client_id は異なりますが、Google API プロジェクトは同じです。
email ユーザーのメールアドレス。この値は、このユーザーに固有のものではなく、主キーとしての使用には適していません。スコープに email スコープ値が含まれている場合にのみ提供されます。
email_verified ユーザーのメールアドレスが確認済みであれば true、それ以外の場合は false。
family_name ユーザーの姓または名。name クレームが存在する場合に提供される可能性があります。
given_name ユーザーの名前または名。name クレームが存在する場合に提供される可能性があります。
hd ユーザーの Google Cloud 組織に関連付けられているドメイン。ユーザーが Google Cloud 組織に属している場合にのみ提供されます。
locale ユーザーの言語 / 地域。BCP 47 言語タグで表されます。 name クレームが存在する場合に提供される可能性があります。
name ユーザーの氏名(表示可能な形式)。以下の状況で通知される場合があります。
  • リクエスト スコープには、文字列「profile&quot」が含まれていました。
  • トークンの更新で ID トークンが返される

name クレームが存在する場合は、それを使用してアプリのユーザー レコードを更新できます。この主張が存在するとは限らないので注意してください。

nonce 認証リクエストでアプリによって提供される nonce の値。リプレイ攻撃に対する保護は一度だけ表示することで、確実に保護する必要があります。
picture ユーザーのプロフィール写真の URL。以下の状況で通知される場合があります。
  • リクエスト スコープには、文字列「profile&quot」が含まれていました。
  • トークンの更新で ID トークンが返される

picture クレームが存在する場合は、それを使用してアプリのユーザー レコードを更新できます。この主張が存在するとは限らないので注意してください。

profile ユーザーのプロフィール ページの URL。以下の状況で通知される場合があります。
  • リクエスト スコープには、文字列「profile&quot」が含まれていました。
  • トークンの更新で ID トークンが返される

profile クレームが存在する場合は、それを使用してアプリのユーザー レコードを更新できます。この主張が存在するとは限らないので注意してください。

6. ユーザーを認証する

ID トークンからユーザー情報を取得したら、アプリのユーザー データベースに対してクエリを実行します。 ユーザーがデータベースにすでに存在する場合、Google API レスポンスですべてのログイン要件を満たしている場合は、そのユーザーのアプリケーション セッションを開始する必要があります。

ユーザーがユーザー データベースに存在しない場合は、ユーザーを新規ユーザーの登録フローにリダイレクトする必要があります。Google から受け取った情報に基づいてユーザーを自動登録できます。少なくとも、登録フォームに必要な項目の多くを事前に入力することもできます。ID トークンの情報に加えて、Google のユーザー プロフィール エンドポイントで追加のユーザー プロフィール情報を取得できます。

高度なトピック

以降のセクションでは、Google OAuth 2.0 API について詳しく説明します。この情報は、認証と認可に関する高度な要件を持つデベロッパーを対象としています。

他の Google API へのアクセス

認証に OAuth 2.0 を使用する利点の 1 つは、ユーザー認証と同時に、アプリケーションが他の Google API(YouTube、Google ドライブ、カレンダー、コンタクトなど)を使用するための権限を取得できることです。これを行うには、Google に送信する認証リクエストに必要な他のスコープを含めます。たとえば、ユーザーの年齢層を認証リクエストに追加するには、scope パラメータを openid email https://www.googleapis.com/auth/profile.agerange.read に渡します。同意画面にユーザーが適切にプロンプトが表示されます。Google から受け取ったアクセス トークンにより、リクエストしたアクセス スコープに関連するすべての API にアクセスできるようになります。

リフレッシュ トークン

API アクセスのリクエストでは、code の交換時に返される更新トークンをリクエストできます。更新トークンを使用すると、ユーザーがアプリケーションに含まれていない間も、アプリから Google API に継続的にアクセスできます。更新トークンをリクエストするには、認証リクエストaccess_type パラメータを offline に設定します。

考慮事項:

  • 更新トークンはコード交換フローの初回実行時にのみ取得できるため、更新トークンは安全かつ永続的に保存してください。
  • 発行される更新トークンの数には上限があります。1 つのクライアントとユーザーの組み合わせごとに 1 つ、すべてのクライアントで 1 つのユーザーごとに上限があります。アプリケーションが更新する更新トークンが多すぎると、これらの制限に達し、古い更新トークンが機能しなくなります。

詳細については、アクセス トークンの更新(オフライン アクセス)をご覧ください。

認証リクエストprompt パラメータを consent に設定すると、ユーザーにアプリの再承認を求めることができます。prompt=consent が含まれている場合は、すべてのスコープが以前に Google API プロジェクトに付与された場合でも、アプリがアクセスのスコープの承認をリクエストするたびに同意画面が表示されます。このため、必要な場合にのみ prompt=consent を含めてください。

prompt パラメータの詳細については、認証 URI パラメータの表の prompt をご覧ください。

認証 URI パラメータ

次の表に、Google の OAuth 2.0 認証 API で利用できるパラメータの詳細を示します。

パラメータ 必須 説明
client_id (必須) API ConsoleCredentials pageから取得したクライアント ID 文字列。OAuth 2.0 認証情報を取得するをご覧ください。
nonce (必須) リプレイ保護を有効にするアプリで生成されるランダム値。
response_type (必須) 値が code の場合、基本認証コードフローを起動し、トークン エンドポイントへの POST でトークンを取得する必要があります。値が token id_token または id_token token の場合、暗黙的フローを起動し、リダイレクト URI で JavaScript を使用して URI #fragment 識別子からトークンを取得する必要があります。
redirect_uri (必須) レスポンスの送信先を指定します。このパラメータの値は、 API ConsoleCredentials page で設定した承認済みのリダイレクト値(HTTP または HTTPS スキーム、ケース、末尾の '/' など)のいずれかと完全に一致する必要があります。
scope (必須)

スコープ パラメータは openid 値で始まり、profile 値、email 値、またはその両方を含む必要があります。

profile スコープ値が存在する場合、ID トークンにユーザーのデフォルトの profile クレームが含まれる可能性があります(ただし、保証される保証はありません)。

email スコープ値が存在する場合、ID トークンには email クレームと email_verified クレームが含まれます。

このような OpenID 固有のスコープに加えて、スコープ引数に他のスコープ値を含めることもできます。すべてのスコープ値はスペースで区切る必要があります。たとえば、ユーザーの Google ドライブにファイルごとのアクセスを指定する場合、scope パラメータを openid profile email https://www.googleapis.com/auth/drive.file のように指定します。

使用可能なスコープについては、Google API の OAuth 2.0 スコープまたは使用する Google API のドキュメントをご覧ください。

state (任意ですが、強くおすすめします)

プロトコルでラウンド トリップされる不透明な文字列。つまり、Basic フローでは URI パラメータとして、暗黙的フローでは URI #fragment 識別子として返されます。

state は、リクエストとレスポンスを関連付けるのに役立ちます。redirect_uri は推測できるため、受信接続がアプリによって開始された認証リクエストの結果として保証される可能性が高くなります。ランダムな文字列を生成する場合や、この state 変数にクライアントの状態(Cookie など)のハッシュをエンコードする場合は、レスポンスを検証することで、リクエストとレスポンスが同じブラウザで行われることを確認できます。これにより、クロスサイト リクエスト フォージェリなどの攻撃から保護できます。

access_type (省略可) 指定できる値は offline および online です。効果については、オフライン アクセスをご覧ください。アクセス トークンがリクエストされている場合、offline の値が指定されない限り、クライアントは更新トークンを受信しません。
display (省略可) 認証サーバーが認証と同意のユーザー インターフェース ページをどのように表示するかを指定する ASCII 文字列値です。pagepopuptouchwap の各値は指定され、Google サーバーで受け入れられますが、動作には影響しません。
hd (省略可)

Google Cloud 組織が所有するアカウントのログイン プロセスを効率化できます。Google Cloud 組織ドメイン(mycollege.edu など)を含めることで、そのドメインのアカウント用にアカウント選択 UI を最適化できます。一般的に 1 つの Google Cloud 組織ドメインではなく Google Cloud 組織アカウント用に最適化するには、アスタリスク(*)の値を設定します。hd=*

クライアント側のリクエストは変更可能なため、この UI の最適化に依存せず、アプリに誰がアクセスできるかを管理しないでください。返された ID トークンhd クレーム値が想定どおりのもの(mycolledge.edu など)であることを検証します。リクエスト パラメータとは異なり、ID トークンの hd クレームは Google からのセキュリティ トークンに含まれているため、その値は信頼できるものです。

include_granted_scopes (省略可) このパラメータの値が true の場合に承認リクエストが送信されると、承認には、他のスコープでユーザーやアプリケーションの組み合わせに付与された以前の承認も含まれます。段階的な承認をご覧ください。

インストール済みアプリのフローでは、段階的な承認はできません。

login_hint (省略可) アプリは、認証しようとしているユーザーを認識している場合に、認証サーバーにヒントとしてこのパラメータを提供できます。このヒントを渡すと、アカウント選択ツールが抑制され、ログイン フォームのメールボックスに情報が自動入力されるか、適切なセッション(ユーザーがマルチログインを使用している場合)が選択されるため、アプリが間違ったユーザー アカウントでログインした場合に発生する問題を回避できます。 値はメールアドレスまたは sub 文字列のいずれかです。これは、ユーザーの Google ID と同等です。
prompt (省略可) 認証サーバーがユーザーに再認証と同意を求めるかどうかを指定する文字列値のスペース区切りリスト。使用できる値は次のとおりです。
  • none

    認可サーバーに認証画面やユーザーの同意画面は表示されません。ユーザーがまだ認証されておらず、リクエストされたスコープに対する同意が事前に構成されていない場合は、エラーが返されます。none を使用すると、既存の認証や同意を確認できます。

  • consent

    認証サーバーは、クライアントに情報を返す前に同意をユーザーに求めます。

  • select_account

    承認サーバーは、ユーザー アカウントを選択するようユーザーに求めます。これにより、認可サーバーに複数のアカウントを持つユーザーが、現在のセッションを担当する複数のアカウントの中から選択することができます。

値が指定されず、ユーザーが以前にアクセスを承認していない場合は、同意画面が表示されます。

ID トークンの検証

Google から直接取得されたものである場合を除き、サーバー上のすべての ID トークンを検証する必要があります。たとえば、サーバーは、クライアント アプリから受け取った ID トークンが本物であることを確認する必要があります。

ID トークンをサーバーに送信する一般的な状況は次のとおりです。

  • 認証が必要なリクエストを含む ID トークンを送信する。ID トークンは、リクエストを行っている特定のユーザーと、その ID トークンが付与されたクライアントを示します。

ID トークンは機密性が高いため、傍受されると悪用される可能性があります。これらのトークンは、HTTPS 経由でのみ、POST データを介して、またはリクエスト ヘッダー内でのみ送信することで、安全に処理されるようにする必要があります。ID トークンをサーバーに保存する場合は、安全に保管する必要があります。

ID トークンの特長の 1 つは、アプリのさまざまなコンポーネントに ID トークンを渡せることです。これらのコンポーネントは、アプリとユーザーを認証するための軽量な認証メカニズムとして ID トークンを使用できます。ただし、ID トークン内の情報を使用したり、ユーザーが認証済みであるというアサーションとして信頼したりする前に、その情報を検証する必要があります

ID トークンを検証するには、いくつかのステップが必要です。

  1. カード発行会社によって ID トークンが適切に署名されていることを確認します。Google が発行したトークンは、ディスカバリ ドキュメントjwks_uri メタデータ値に指定された URI で見つかった証明書のいずれかを使用して署名されます。
  2. ID トークン内の iss クレームの値が https://accounts.google.com または accounts.google.com と等しいことを確認します。
  3. ID トークン内の aud クレームの値がアプリのクライアント ID と等しいことを確認します。
  4. ID トークンの有効期限(exp クレーム)が経過していないことを確認します。
  5. リクエストで hd パラメータの値を指定した場合は、Google Cloud 組織に関連付けられた承認済みドメインと一致する hd クレームが ID トークンにあることを確認します。

ステップ 2 から 5 には文字列比較と日付比較のみが含まれています。非常に単純なので、ここでは詳しく説明しません。

最初のステップはより複雑で、暗号署名チェックが必要です。デバッグ目的では、Google の tokeninfo エンドポイントを使用して、サーバーまたはデバイスに実装されたローカル処理と比較できます。ID トークンの値が XYZ123 とします。この場合、URI https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123 の参照を解除します。トークン署名が有効な場合、レスポンスはデコードされた JSON オブジェクト形式の JWT ペイロードになります。

tokeninfo エンドポイントはデバッグに役立ちますが、本番環境では、キー エンドポイントから Google の公開鍵を取得してローカルで検証します。jwks_uri メタデータ値を使用して、ディスカバリ ドキュメントからキー URI を取得する必要があります。デバッグ エンドポイントへのリクエストは、スロットルされたり、断続的なエラーの影響を受けたりする可能性があります。

Google が公開鍵を変更する頻度は低いため、HTTP レスポンスのキャッシュ ディレクティブを使用して公開鍵をキャッシュに保存できます。ほとんどの場合、ローカル検証は tokeninfo エンドポイントを使用するよりもはるかに効率的です。この検証では、証明書を取得して解析し、適切な暗号呼び出しを行って、署名をチェックする必要があります。幸い、デバッグのためのさまざまなライブラリがさまざまな言語で利用できます(jwt.io をご覧ください)。

ユーザー プロフィール情報の取得

ユーザーに関する追加のプロファイル情報を取得するには、アクセス トークン(認証フロー中にアプリケーションが受信するアクセス トークン)と OpenID Connect 標準を使用します。

  1. OpenID 準拠にするには、認証リクエストopenid profile スコープ値を含める必要があります。

    ユーザーのメールアドレスを含める場合は、追加のスコープ値 email を指定できます。profileemail の両方を指定するには、認証リクエスト URI に次のパラメータを含めます。

    scope=openid%20profile%20email
  2. アクセス トークンを承認ヘッダーに追加し、HTTPS GET リクエストを userinfo エンドポイントに送信します。これは、ディスカバリ ドキュメントから userinfo_endpoint メタデータ値を使用して取得する必要があります。OpenID Connect Standard Claims とディスカバリ ドキュメントの claims_supported メタデータ値で説明されているように、userinfo のレスポンスにはユーザーに関する情報が含まれています。ユーザーまたはその組織は特定のフィールドを指定または除外できるため、承認済みアクセスの範囲に関するすべてのフィールドの情報を取得できないことがあります。

ディスカバリ ドキュメント

OpenID Connect プロトコルでは、ユーザーの認証のため、およびトークン、ユーザー情報、公開鍵などのリソースをリクエストするために、複数のエンドポイントを使用する必要があります。

OpenID Connect では実装を簡素化し、柔軟性を高めるために、「探す」ドキュメント、Key-Value ペアなど、既知の場所にある JSON ドキュメントを使用できます。これにより、OpenID Connect プロバイダの構成に関する詳細情報(認証、トークン、取り消し、userinfo、公開鍵のエンドポイントなど)が提供されます。Google の OpenID Connect サービスのディスカバリ ドキュメントは、以下から取得できます。

https://accounts.google.com/.well-known/openid-configuration

Google の OpenID Connect サービスを使用するには、Discovery ドキュメント URI(https://accounts.google.com/.well-known/openid-configuration)をアプリケーションにハードコードする必要があります。アプリケーションは、ドキュメントを取得してレスポンスにキャッシュ ルールを適用し、必要に応じてエンドポイント URI を取得します。たとえば、ユーザーを認証するために、コードは authorization_endpoint メタデータ値(以下の例では https://accounts.google.com/o/oauth2/v2/auth)を Google に送信される認証リクエストのベース URI として取得します。

このようなドキュメントの例を次に示します。フィールド名は OpenID Connect Discovery 1.0 で指定されている名前です(ドキュメントの意味については、各ドキュメントをご覧ください)。値はあくまでも例示であり、実際の Google Discovery ドキュメントの最新バージョンからコピーされた可能性があります。

{
  "issuer": "https://accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
  "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
  "token_endpoint": "https://oauth2.googleapis.com/token",
  "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
  "revocation_endpoint": "https://oauth2.googleapis.com/revoke",
  "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
  "response_types_supported": [
    "code",
    "token",
    "id_token",
    "code token",
    "code id_token",
    "token id_token",
    "code token id_token",
    "none"
  ],
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "scopes_supported": [
    "openid",
    "email",
    "profile"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic"
  ],
  "claims_supported": [
    "aud",
    "email",
    "email_verified",
    "exp",
    "family_name",
    "given_name",
    "iat",
    "iss",
    "locale",
    "name",
    "picture",
    "sub"
  ],
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ]
}

ディスカバリ ドキュメントからの値をキャッシュに保存することで、HTTP のラウンドトリップを回避できる場合があります。標準の HTTP キャッシュ ヘッダーが使用され、これに従う必要があります。

クライアント ライブラリ

次のクライアント ライブラリでは、よく使用されるフレームワークと統合することで OAuth 2.0 の実装が簡単になります。

OpenID Connect コンプライアンス

Google の OAuth 2.0 認証システムは、OpenID Connect Core 仕様の必須機能をサポートしています。OpenID Connect で動作するように設計されたクライアントは、このサービスと相互運用する必要があります(OpenID Request オブジェクトを除く)。