このドキュメントでは、スマートフォン、タブレット、パソコンなどのデバイスにインストールされたアプリが Google の OAuth 2.0 エンドポイントを使用して Google API へのアクセスを承認する方法について説明します。
OAuth 2.0 では、ユーザー名やパスワードなどの情報を秘密にしたまま、ユーザーが特定のデータをアプリケーションと共有できます。たとえば、アプリケーションで OAuth 2.0 を使い、Google ドライブにファイルを保存する許可をユーザーから取得できます。
インストールされたアプリは個々のデバイスに配布され、これらのアプリはシークレットを保持できないと想定されています。ユーザーがアプリを使用しているときや、アプリがバックグラウンドで実行されているときに、Google API にアクセスできます。
この認可フローは、ウェブサーバー アプリケーションで使用されるものと似ています。主な違いは、インストールされたアプリがシステム ブラウザを開き、Google の認証サーバーからのレスポンスを処理するためのローカル リダイレクト URI を提供する必要があることです。
ライブラリとサンプル
iOS アプリの場合は、 Google でログイン iOS SDK の最新バージョンを使用することをおすすめします。SDK はユーザー認証を処理し、このガイドで説明する下位レベルのプロトコルよりも実装が簡単です。
システム ブラウザをサポートしていないデバイスや、テレビ、ゲーム機、カメラ、プリンタなど入力機能が制限されているデバイスで実行されるアプリについては、TV&デバイス用 OAuth 2.0 またはテレビと入力機能が限られたデバイスでのログインをご覧ください。
前提条件
プロジェクトでAPI を有効にする
Google API を呼び出すアプリケーションは、API Console でそれらの API を有効にする必要があります。
プロジェクトで API を有効にするには:
- Google API Console で API ライブラリを開きます。
- プロンプトが表示されたら、プロジェクトのいずれかを選択するか、新しいプロジェクトを作成します。
- API ライブラリには、利用できるすべての API が製品ファミリーと人気度によって分類、表示されます。有効にする API がリストで見当たらない場合は、検索して見つけるか、その API が属するプロダクト ファミリーの [すべて表示] をクリックします。
- 有効にする API を選択し、[有効にする] ボタンをクリックします。
- プロンプトが表示されたら、請求機能を有効にします。
- プロンプトが表示されたら、API の利用規約を確認し、同意します。
承認認証情報を作成する
OAuth 2.0 を使用して Google API にアクセスするアプリケーションは、Google の OAuth 2.0 サーバーに対して自身の身元を示す認証情報を持つ必要があります。次の手順では、プロジェクトの認証情報を作成する方法について説明します。アプリケーションは、この認証情報を使用して、そのプロジェクトで有効にした API にアクセスできます。
- [クライアント] ページに移動します。
- [クライアントの作成] をクリックします。
- 以降のセクションでは、Google の認可サーバーがサポートするクライアント タイプについて説明します。アプリケーションに推奨されるクライアント タイプを選択し、OAuth クライアントに名前を付け、フォームの他のフィールドを適宜設定します。
iOS
- アプリケーションの種類として [iOS] を選択します。
- OAuth クライアントの名前を入力します。この名前は、プロジェクトのクライアント ページに表示され、クライアントを識別するために使用されます。
- アプリのバンドル識別子を入力します。バンドル ID は、アプリの情報プロパティ リスト リソース ファイル(info.plist)の CFBundleIdentifier キーの値です。この値は、通常、Xcode プロジェクト エディタの [General] ペインまたは [Signing & Capabilities] ペインに表示されます。バンドル ID は、Apple の App Store Connect サイトのアプリの [App Information] ページの [General Information] セクションにも表示されます。
App Check 機能を使用している場合は、アプリに正しいバンドル ID を使用していることを確認してください。この ID は変更できません。
- (省略可)
アプリが Apple の App Store で公開されている場合は、アプリの App Store ID を入力します。ストア ID は、すべての Apple App Store URL に含まれる数字の文字列です。
- iOS または iPadOS デバイスで Apple App Store アプリを開きます。
- アプリを検索します。
- 共有ボタン(四角と上向き矢印の記号)を選択します。
- [リンクをコピー] を選択します。
- リンクをテキスト エディタに貼り付けます。App Store ID は URL の末尾部分です。
例:
https://apps.apple.com/app/google/id284815942
- (省略可)
チーム ID を入力します。詳しくは、Apple Developer Account のドキュメントのチーム ID を確認するをご覧ください。
注: クライアントで App Check を有効にする場合は、[チーム ID] フィールドが必要です。 - (省略可)
iOS アプリで App Check を有効にします。App Check を有効にすると、Apple の App Attest サービスが使用され、OAuth クライアントから送信された OAuth 2.0 リクエストが正規のものであり、アプリから送信されたものであることが確認されます。これにより、アプリのなりすましのリスクを軽減できます。iOS アプリで App Check を有効にする方法の詳細。
- [作成] をクリックします。
UWP
- [ユニバーサル Windows プラットフォーム] アプリケーションの種類を選択します。
- OAuth クライアントの名前を入力します。この名前は、クライアントを識別するためにプロジェクトの に表示されます。
- アプリの 12 文字の Microsoft Store ID を入力します。この値は、Microsoft パートナー センターの [アプリ管理] セクションにある [アプリ ID] ページで確認できます。
- [作成] をクリックします。
UWP アプリの場合、リダイレクト URI は、アプリケーションの一意のパッケージ セキュリティ識別子(SID)を使用して形成されます。アプリの Package SID は、Visual Studio プロジェクト内の Package.appxmanifest ファイルにあります。
Google Cloud コンソールでクライアント ID を作成するときは、パッケージ SID の小文字の値を使用して、次の形式でリダイレクト URI を指定する必要があります。
ms-app://YOUR_APP_PACKAGE_SID
UWP アプリの場合、カスタム URI スキームは Microsoft のドキュメントで指定されているように、39 文字以下にする必要があります。
アクセス スコープを特定する
スコープを指定すると、アプリケーションからのアクセス要求は必要なリソースのみに限定されるようになり、ユーザーはアプリケーションに付与するアクセスレベルを制御できます。したがって、リクエストされるスコープの数とユーザーの同意を得られる可能性の間には、逆相関がある可能性があります。
OAuth 2.0 認証の実装を開始する前に、アプリがアクセス権限を必要とするスコープを設定しておくことをおすすめします。
OAuth 2.0 API スコープのドキュメントには、Google API へのアクセスに使用できるスコープの完全なリストが記載されています。
OAuth 2.0 アクセス トークンを取得する
次の手順は、アプリケーションが Google の OAuth 2.0 サーバーと連携して、ユーザーに代わって API リクエストを実行するためのユーザーの同意を得る方法を示しています。ユーザーの承認が必要な Google API リクエストを実行するには、アプリがその同意を得ている必要があります。
ステップ 1: コード検証ツールとチャレンジを生成する
Google は、インストール済みのアプリのフローをより安全にするために、Proof Key for Code Exchange(PKCE)プロトコルをサポートしています。認可リクエストごとに一意のコード ベリファイアが作成され、その変換された値(「code_challenge」)が認可サーバーに送信されて、認証コードが取得されます。
コード検証ツールを作成する
code_verifier は、予約されていない文字 [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" を使用した高エントロピーの暗号論的ランダム文字列です。最小長は 43 文字、最大長は 128 文字です。
コード検証ツールは、値を推測することが実質的に不可能なほどのエントロピーを備えている必要があります。
コードチャレンジを作成する
コードチャレンジの作成方法は 2 つあります。
| コードチャレンジの生成方法 | |
|---|---|
| S256(推奨) | コードチャレンジは、コード検証ツールの Base64URL(パディングなし)でエンコードされた SHA256 ハッシュです。
|
| plain | コードチャレンジは、上記で生成されたコード検証ツールと同じ値です。
|
ステップ 2: Google の OAuth 2.0 サーバーにリクエストを送信する
ユーザーの承認を取得するには、https://accounts.google.com/o/oauth2/v2/auth の Google 認可サーバーにリクエストを送信します。このエンドポイントは、アクティブなセッションのルックアップを処理し、ユーザーを認証して、ユーザーの同意を取得します。このエンドポイントは SSL 経由でのみアクセス可能で、HTTP(非 SSL)接続は拒否されます。
認証サーバーは、インストール済みアプリに対して次のクエリ文字列パラメータをサポートしています。
| パラメータ | |||||||
|---|---|---|---|---|---|---|---|
client_id |
必須
アプリケーションのクライアント ID。この値は、Cloud Console の [クライアント] ページで確認できます。 |
||||||
redirect_uri |
必須
Google の認可サーバーがアプリにレスポンスを送信する方法を決定します。インストール済みアプリには複数のリダイレクト オプションがあり、特定のメソッドを念頭に置いて認可情報を設定する必要があります。 この値は、クライアントの Cloud コンソールのクライアント ページで構成した OAuth 2.0 クライアントの承認済みリダイレクト URI のいずれかと完全に一致する必要があります。この値が承認済み URI と一致しない場合、 次の表に、各メソッドの適切な
|
||||||
response_type |
必須
Google OAuth 2.0 エンドポイントが認証コードを返すかどうかを決定します。 インストールされたアプリのパラメータ値を |
||||||
scope |
必須
アプリケーションがユーザーの代わりにアクセスできるリソースを識別するスコープのスペース区切りリスト。これらの値は、Google がユーザーに表示する同意画面に反映されます。 スコープを指定すると、アプリケーションからのアクセス要求は必要なリソースのみに限定されるようになり、ユーザーはアプリケーションに付与するアクセスレベルを制御できます。したがって、リクエストされるスコープの数とユーザーの同意が得られる可能性の間には逆相関があります。 |
||||||
code_challenge |
推奨
認可コード交換時にサーバーサイドのチャレンジとして使用されるエンコードされた |
||||||
code_challenge_method |
推奨
認証コードの交換時に使用される |
||||||
state |
推奨
認可リクエストと認可サーバーのレスポンスの間で状態を維持するためにアプリケーションが使用する文字列値を指定します。ユーザーがアプリのアクセス リクエストを承認または拒否すると、サーバーは このパラメータは、ユーザーをアプリケーション内の正しいリソースに誘導する、ノンスを送信する、クロスサイト リクエスト フォージェリを軽減するなど、さまざまな目的で使用できます。 |
||||||
login_hint |
省略可
アプリが認証を試みているユーザーを把握している場合は、このパラメータを使用して Google 認証サーバーにヒントを提供できます。サーバーは、ログイン フォームのメール フィールドを事前入力するか、適切なマルチログイン セッションを選択することで、ヒントを使用してログイン フローを簡素化します。 パラメータ値をメールアドレスまたは |
||||||
認証 URL の例
以下のタブは、さまざまなリダイレクト URI オプションの認証 URL の例を示しています。
redirect_uri パラメータの値を除いて、URL は同じです。URL には、必須の response_type パラメータと client_id パラメータ、オプションの state パラメータも含まれています。各 URL には、読みやすくするために改行とスペースが含まれています。
カスタム URI スキーム
https://accounts.google.com/o/oauth2/v2/auth? scope=email%20profile& response_type=code& state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken& redirect_uri=com.example.app%3A/oauth2redirect& client_id=client_id
ループバック IP アドレス
https://accounts.google.com/o/oauth2/v2/auth? scope=email%20profile& response_type=code& state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken& redirect_uri=http%3A//127.0.0.1%3A9004& client_id=client_id
ステップ 3: Google がユーザーに同意を求める
このステップで、ユーザーはリクエストされたアクセス権をアプリに付与するかどうかを決定します。この段階で、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 ポリシーで禁止されている埋め込みユーザー エージェント内に表示されます。
iOS と macOS のデベロッパーは、WKWebView で承認リクエストを開くときにこのエラーが発生することがあります。代わりに、デベロッパーは Google ログイン for iOS や OpenID Foundation の AppAuth for iOS などの iOS ライブラリを使用する必要があります。
ウェブ デベロッパーは、iOS または macOS アプリが埋め込みユーザー エージェントで一般的なウェブリンクを開き、ユーザーがサイトから Google の OAuth 2.0 認可エンドポイントに移動したときに、このエラーに遭遇する可能性があります。デベロッパーは、ユニバーサル リンク ハンドラまたはデフォルトのブラウザアプリを含む、オペレーティング システムのデフォルトのリンク ハンドラで一般的なリンクを開けるようにする必要があります。SFSafariViewController ライブラリもサポートされているオプションです。
org_internal
リクエストの OAuth クライアント ID は、特定の Google Cloud 組織内の Google アカウントへのアクセスを制限するプロジェクトの一部です。この構成オプションの詳細については、OAuth 同意画面の設定に関するヘルプ記事のユーザータイプのセクションをご覧ください。
deleted_client
リクエストの作成に使用されている OAuth クライアントが削除されました。削除は、手動で行うことも、未使用のクライアント の場合は自動で行うこともできます。削除したクライアントは、削除後 30 日以内であれば復元できます。詳細
invalid_grant
コード検証ツールとチャレンジを使用している場合、code_callenge パラメータが無効であるか、指定されていません。code_challenge パラメータが正しく設定されていることを確認します。
アクセス トークンを更新する場合、トークンの有効期限が切れているか、無効になっている可能性があります。ユーザーを再度認証し、新しいトークンを取得するためのユーザーの同意を求めます。このエラーが引き続き表示される場合は、アプリケーションが正しく構成されていること、リクエストで正しいトークンとパラメータを使用していることを確認してください。それ以外の場合は、ユーザー アカウントが削除または無効になっている可能性があります。
redirect_uri_mismatch
認可リクエストで渡された redirect_uri が、OAuth クライアント ID の承認済みリダイレクト URI と一致しません。Google Cloud コンソールの [クライアント] ページで、承認済みリダイレクト URI を確認します。
渡された redirect_uri は、クライアント タイプに対して無効である可能性があります。
redirect_uri パラメータは、非推奨となりサポートが終了した OAuth 帯域外(OOB)フローを参照している可能性があります。統合を更新するには、移行ガイドを参照してください。
invalid_request
リクエストに問題がありました。これには、次のような理由が考えられます。
- リクエストの形式が正しくありませんでした
- リクエストに必須パラメータが含まれていませんでした
- リクエストで、Google がサポートしていない認証方法が使用されています。OAuth 統合で推奨される統合方法が使用されていることを確認する
- リダイレクト URI にサポートされていないカスタム スキームが使用されました。[ Custom URI scheme is not supported on Android or Chrome apps](カスタム URI スキームは Android アプリまたは Chrome アプリでサポートされていません)というエラー メッセージが表示された場合は、カスタム URI スキームの代替手段について詳細をご確認ください。
ステップ 4: OAuth 2.0 サーバーのレスポンスを処理する
アプリケーションが認証レスポンスを受け取る方法は、使用するリダイレクト URI スキームによって異なります。スキームに関係なく、レスポンスには認証コード(code)またはエラー(error)が含まれます。たとえば、error=access_denied は、ユーザーがリクエストを拒否したことを示します。
ユーザーがアプリへのアクセスを許可すると、次のステップで説明するように、認証コードをアクセス トークンと更新トークンに交換できます。
ステップ 5: 認証コードを更新トークンとアクセス トークンに交換する
認可コードをアクセス トークンと交換するには、https://oauth2.googleapis.com/token エンドポイントを呼び出し、次のパラメータを設定します。
| フィールド | |
|---|---|
client_id |
Cloud Console の [クライアント] ページから取得したクライアント ID。 |
client_secret |
省略可
Cloud Console のクライアント ページから取得したクライアント シークレット。 |
code |
初回リクエストから返された認証コード。 |
code_verifier |
手順 1 で作成したコード検証ツール。 |
grant_type |
OAuth 2.0 仕様で定義されているように、このフィールドの値は authorization_code に設定する必要があります。 |
redirect_uri |
指定された client_id の Cloud Console の [クライアント] ページに表示されているプロジェクトのリダイレクト URI のいずれか。 |
DPoP の使用は任意ですが、セキュリティ強化のためにおすすめします。DPoP のセキュリティは、秘密鍵が単一のデバイスに制限されていることに依存しています。TPM、セキュア エンクレーブ、その他のハードウェア格納型キーストアなどを使用して、秘密鍵をデバイス外にコピーできないように保存することをおすすめします。DPoP を使用するには、アプリケーションでトークン エンドポイントへのリクエストごとに新しい一意の DPoP 証明 JWT を生成し、HTTP リクエスト ヘッダーとして追加する必要があります。
| ヘッダー | 必須 | 説明 |
|---|---|---|
DPoP |
省略可 | DPoP 証明は、秘密鍵の所有を証明する JWT です。これはパラメータではなくヘッダーです。指定した場合、返されるトークンはこのキーにバインドされます。リクエストごとに新しい一意の証明を生成し、リクエストと一致する htm(HTTP メソッド)と htu(HTTP URI)のクレームを含める必要があります。 |
次のスニペットは、リクエストの例を示しています。
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\ VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\ nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\ QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\ oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\ WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\ 4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& redirect_uri=http://127.0.0.1:9004& grant_type=authorization_code
DPoP 証明を構築する
次の手順では、コマンドラインから OpenSSL を使用して DPoP 証明を作成する方法を示します。
- EC P-256 鍵ペアを生成します。
openssl ecparam -name prime256v1 -genkey -noout -out dpop_private.pem openssl ec -in dpop_private.pem -pubout -out dpop_public.pem
- DPoP ヘッダーを作成します。
ヘッダーには、
typ、alg、jwk(公開鍵)の各クレームを含める必要があります。xとyの値は、EC 公開鍵の Base64Url エンコードされた座標です。この JSON を Base64Url でエンコードします。{ "typ":"dpop+jwt", "alg":"ES256", "jwk": { "kty":"EC", "x":"YOUR_PUBLIC_KEY_X", "y":"YOUR_PUBLIC_KEY_Y", "crv":"P-256" } } - DPoP ペイロードを作成します。
ペイロードには、
jti(リクエストの一意の識別子)、htm(HTTP メソッド、例:POST)、htu(HTTP URI、例:https://oauth2.googleapis.com/token)、iat(発行時刻)を含める必要があります。前のリクエストのレスポンスのDPoP-Nonceヘッダーでサーバーから nonce を受け取った場合は、その nonce 値をnonceクレームに含める必要があります。nonce クレームは、認証コード交換では省略可能であり、DPoP-Nonce ヘッダーが以前に受信された場合にのみ使用されます。この JSON を Base64Url でエンコードします。{ "jti":"JTI_VALUE", "htm":"POST", "htu":"https://oauth2.googleapis.com/token", "iat":YOUR_JWT_ISSUED_TIME, "nonce":"SERVER_PROVIDED_NONCE" }jtiの値は、エクスチェンジのタイプによって異なります。- 認証コードの交換の場合、
jtiは認証コードの Base64Url エンコードされた SHA256 ハッシュ("jti":"BASE64URL(SHA256(AUTHORIZATION_CODE))")である必要があります。 - 更新トークンの交換の場合、
jtiはリクエストごとに一意の識別子("jti":"YOUR_UNIQUE_PER_REQUEST_IDENTIFIER")である必要があります。
- 認証コードの交換の場合、
- 証明に署名します。
エンコードされたヘッダーとペイロードをピリオド(
.)で連結し、ES256 を使用して秘密鍵で結果に署名します。JWS では、署名が未加工のR | S連結形式(P-256 の場合は 64 バイト)である必要があります。OpenSSL を直接使用する場合は、デフォルトの ASN.1 DER エンコード署名をこの未加工形式に変換する必要があります。
交換が成功すると、トークンを含む 200 OK レスポンスが返されます。交換時に有効な DPoP 証明が使用されると、Google が返す更新トークンは鍵に DPoP バインドされますが、アクセス トークンは DPoP バインドされません。アクセス トークンは、DPoP ではなく Bearer の token_type を保持します。また、Google はレスポンスで DPoP-Nonce HTTP ヘッダーを返します。クライアントは、このノンスをキャッシュに保存し、後続のリクエスト(更新トークンを新しいアクセス トークンと交換する場合や、DPoP で保護された API を呼び出す場合など)の DPoP 証明の nonce クレームに含める必要があります。この早期発行された nonce を使用することで、次のリクエストで余分なラウンド トリップの失敗(use_dpop_nonce)を回避できます。
DPoP バインド リフレッシュ トークンを使用して行われたトークン交換リクエストには、DPoP 証明を含める必要があります。
DPoP ヘッダーが想定どおりに存在しないか、無効であるか、証明書がトークンにバインドされている鍵とは異なる鍵を使用している場合、交換の失敗が発生します。このような場合、サーバーは 400 Bad Request エラーを返します。DPoP 証明に一致しない htm または htu クレーム、期限切れの iat、再利用された jti、無効な署名がある場合、Google は invalid_dpop_proof エラーコードを返します。更新トークンの交換時など、DPoP ノンスが必要な場合に、DPoP 証明書に nonce クレームがないか、ノンス値がサーバーで受け入れられない(期限切れ、すでに使用済み、正しくないなど)場合、Google は use_dpop_nonce エラーコードと、後続のリクエストで使用できる新しいノンスを含む DPoP-Nonce HTTP ヘッダーを返します。他の障害では invalid_grant が返されることがあります。
Google は、このリクエストに応答して、有効期間の短いアクセス トークンと更新トークンを含む JSON オブジェクトを返します。
レスポンスには、次のフィールドが含まれます。
| フィールド | |
|---|---|
access_token |
Google API リクエストを承認するためにアプリケーションが送信するトークン。 |
expires_in |
アクセス トークンの残りの有効期間(秒単位)。 |
id_token |
注: このプロパティは、リクエストに openid、profile、email などの ID スコープが含まれている場合にのみ返されます。値は、ユーザーに関するデジタル署名された ID 情報を含む JSON Web Token(JWT)です。 |
refresh_token |
新しいアクセス トークンを取得するために使用できるトークン。更新トークンは、ユーザーがアクセスを取り消すか、更新トークンの有効期限が切れるまで有効です。DPoP が使用された場合、更新トークンは DPoP 証明の署名に使用された秘密鍵にバインドされます。インストールされたアプリケーションに対しては、常に更新トークンが返されることに注意してください。 |
refresh_token_expires_in |
更新トークンの残りの有効期間(秒単位)。この値は、ユーザーが時間ベースのアクセスを許可した場合にのみ設定されます。 |
scope |
access_token によって付与されたアクセス権のスコープ。スペース区切りの大文字と小文字が区別される文字列のリストとして表現されます。 |
token_type |
返されるトークンのタイプ。この値は、DPoP が使用されている場合でも常に Bearer です。 |
次のスニペットは、DPoP が使用されている場合の成功したレスポンス ヘッダーと本文のサンプルを示しています。
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"token_type": "Bearer",
"scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
"refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}ステップ 6: ユーザーがどのスコープを付与したかを確認する
複数の権限(スコープ)をリクエストした場合、ユーザーがアプリにすべての権限へのアクセスを許可するとは限りません。アプリは、実際に付与されたスコープを確認し、一部の権限が拒否された状況に適切に対応する必要があります。通常は、拒否されたスコープに依存する機能を無効にします。
ただし、例外もあります。ドメイン全体の権限の委任が設定されている Google Workspace Enterprise アプリ、または [信頼できる] とマークされているアプリは、詳細な権限の同意画面を省略します。これらのアプリでは、ユーザーにきめ細かい権限の同意画面は表示されません。代わりに、アプリはリクエストされたすべてのスコープを受け取るか、1 つも受け取らないかのどちらかになります。
詳しくは、きめ細かい権限を処理する方法をご覧ください。
ユーザーが特定のスコープへのアクセス権をアプリケーションに付与しているかどうかを確認するには、アクセス トークン レスポンスの scope フィールドを調べます。access_token によって付与されたアクセス権のスコープ。スペース区切りの大文字と小文字が区別される文字列のリストとして表されます。
たとえば、次のサンプル アクセス トークン レスポンスは、ユーザーが読み取り専用のドライブ アクティビティとカレンダーの予定の権限をアプリに付与したことを示しています。
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
Google API を呼び出す
アプリケーションがアクセス トークンを取得した後、API で必要なアクセス スコープが付与されている場合は、トークンを使用して特定のユーザー アカウントの代わりに Google API を呼び出すことができます。これを行うには、access_token クエリ パラメータまたは Authorization HTTP ヘッダー Bearer 値のいずれかを含めることで、API へのリクエストにアクセス トークンを含めます。クエリ文字列はサーバーログに表示される傾向があるため、可能な場合は HTTP ヘッダーを使用することをおすすめします。ほとんどの場合、クライアント ライブラリを使用して Google API への呼び出しを設定できます(たとえば、Drive Files API を呼び出す場合など)。
OAuth 2.0 Playground では、すべての Google API を試して、そのスコープを確認できます。
HTTP GET の例
Authorization: Bearer HTTP ヘッダーを使用して
drive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.filesdrive.files�独自のアクセス トークンを指定する必要があります。
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
以下は、access_token クエリ文字列パラメータを使用して認証済みユーザーに対して同じ API を呼び出す例です。
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
curl の例
これらのコマンドは、curl コマンドライン アプリケーションでテストできます。HTTP ヘッダー オプション(推奨)を使用する例を次に示します。
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
または、クエリ文字列パラメータ オプションを使用します。
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
アクセス トークンを更新する
アクセス トークンは定期的に期限が切れ、関連する API リクエストに対して無効な認証情報になります。トークンに関連付けられたスコープへのオフライン アクセスをリクエストした場合は、ユーザーに権限を求めることなく(ユーザーが不在の場合を含めて)アクセス トークンを更新できます。
アクセス トークンを更新するには、アプリケーションが 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 |
認証コード交換から返された更新トークン。 |
DPoP の使用は任意ですが、セキュリティ強化のためにおすすめします。更新トークンで DPoP を使用するには、トークン エンドポイントへのリクエストごとに、新しい一意の DPoP 証明 JWT を生成する必要があります。この証明は、最初の認証コード交換で使用されたものと同じ秘密鍵で署名する必要があります。アプリケーションは、証明を HTTP リクエスト ヘッダーとして追加します。
| ヘッダー | 必須 | 説明 |
|---|---|---|
DPoP |
省略可 | DPoP 証明は、秘密鍵の所有を証明する JWT です。これはパラメータではなくヘッダーです。指定した場合、返されるトークンはこのキーにバインドされます。リクエストごとに新しい一意の証明を生成し、リクエストと一致する htm(HTTP メソッド)と htu(HTTP URI)のクレームを含める必要があります。 |
次のスニペットは、リクエストの例を示しています。
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded DPoP: DPOP_PROOF_JWT client_id=your_client_id& refresh_token=refresh_token& grant_type=refresh_token
更新トークンで DPoP を使用するには、リクエスト用に新しい一意の DPoP 証明 JWT を生成する必要があります。鍵ペアの生成と JWT の構築の手順については、DPoP 証明を構築するをご覧ください。
交換が成功すると、新しいアクセス トークンを含む 200 OK レスポンスが返されます。DPoP を使用する場合、token_type は Bearer です。成功レスポンスは、更新トークンの DPoP 証明が受け入れられたことを確認します。Google はレスポンスで新しい DPoP-Nonce HTTP ヘッダーを返すこともあります。返された場合、クライアントはこのノンスをキャッシュに保存し、後続のリクエストの DPoP 証明の nonce クレームに含める必要があります。
DPoP ヘッダーがないか、無効であるか、間違ったキーを使用している場合、交換が失敗します。特定の DPoP エラーコードとノンスの処理について詳しくは、交換の失敗をご覧ください。
次のスニペットは、DPoP が使用されている場合の成功したレスポンス ヘッダーと本文のサンプルを示しています。
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
DPoP-Nonce: AN3XwJjZsjnb0ZuWkRlek8QU7wY-Zhf-5IP6tO0tORz0KgtDT1Bo8FX-w4nz3r5lnepI
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
"token_type": "Bearer"
}発行される更新トークンの数には上限があります。クライアントとユーザーの組み合わせごとに 1 つの上限と、すべてのクライアントのユーザーごとに 1 つの上限があります。更新トークンは長期ストレージに保存し、有効な限り使用し続ける必要があります。アプリケーションが過剰な数の更新トークンをリクエストすると、これらの上限に達する可能性があります。その場合、古い更新トークンは機能しなくなります。
トークンの取り消し
ユーザーがアプリに付与したアクセス権を取り消したい場合もあります。ユーザーは、 アカウント設定にアクセスしてアクセス権を取り消すことができます。詳しくは、アカウントにアクセスできるサードパーティのサイトやアプリのサポート ドキュメントの「サイトやアプリのアクセス権を削除する」セクションをご覧ください。
アプリケーションが、自身に付与されたアクセス権をプログラムで取り消すことも可能です。ユーザーが登録を解除した場合、アプリを削除した場合、アプリに必要な API リソースが大幅に変更された場合などには、プログラムによる取り消しが重要になります。つまり、削除プロセスの一部として、以前にアプリに付与された権限が削除されるように API リクエストを含めることができます。
プログラムでトークンを取り消すには、アプリケーションが https://oauth2.googleapis.com/revoke にリクエストを送信し、トークンをパラメータとして含めます。
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
https://oauth2.googleapis.com/revoke?token={token}トークンはアクセス トークンまたは更新トークンです。トークンがアクセス トークンで、対応する更新トークンがある場合、更新トークンも取り消されます。
取り消しが正常に処理されると、レスポンスの HTTP ステータス コードは 200 になります。エラー条件の場合、エラーコードとともに HTTP ステータス コード 400 が返されます。
アプリのリダイレクト方法
カスタム URI スキーム
カスタム URI スキームは、カスタム定義のスキームを使用してアプリを開くディープリンクの一種です。
Chrome アプリでカスタム URI スキームを使用する代替手段
Chrome Identity API を使用します。この API は OAuth 2.0 レスポンスをアプリに直接配信するため、リダイレクト URI は不要になります。
ループバック IP アドレス(macOS、Linux、Windows デスクトップ)
この URL を使用して認証コードを受け取るには、アプリケーションがローカル ウェブサーバーでリッスンしている必要があります。これは多くのプラットフォームで可能ですが、すべてのプラットフォームで可能というわけではありません。ただし、プラットフォームがサポートしている場合は、これが認証コードを取得するための推奨メカニズムです。
アプリが認証レスポンスを受け取ったら、ユーザーにブラウザを閉じてアプリに戻るよう指示する HTML ページを表示して応答するのが、ユーザビリティの面で最適です。
| 推奨される使い方 | macOS、Linux、Windows デスクトップ(ユニバーサル Windows プラットフォームを除く)アプリ |
| フォームの値 | アプリケーション タイプを [デスクトップ アプリ] に設定します。 |
手動コピー/貼り付け(非推奨)
アプリを保護する
Chrome のアプリの所有権を確認する
アプリケーションの所有権を確認することで、アプリのなりすましのリスクを軽減できます。
確認手続きを完了するには、Chrome ウェブストア デベロッパー アカウントを使用します。確認手続きを完了するには、次の要件を満たす必要があります。
- 確認を完了する Chrome 拡張機能 OAuth クライアントと同じ商品アイテム ID のアイテムが、Chrome ウェブストア デベロッパー ダッシュボードに登録されている必要があります。
- Chrome ウェブストア アイテムのパブリッシャーである必要があります。Chrome ウェブストア デベロッパー ダッシュボードでのアクセス管理について詳しくは、こちらをご覧ください。
Chrome 拡張機能クライアントの [Verify App Ownership] セクションで、[Verify Ownership] ボタンをクリックして確認プロセスを完了します。
注: アカウントへのアクセス権を付与した後、検証プロセスを完了するまでに数分待ちます。
確認が成功すると、確認プロセスの成功を確認する通知が表示されます。それ以外の場合は、エラー プロンプトが表示されます。
確認に失敗した場合は、次の手順をお試しください。
- Chrome ウェブストア デベロッパー ダッシュボードに、確認を完了しようとしている Chrome 拡張機能 OAuth クライアントと同じ商品アイテム ID の登録済みアイテムがあることを確認します。
- アプリのパブリッシャーであることを確認します。つまり、アプリの個人パブリッシャーであるか、アプリのグループ投稿者のメンバーである必要があります。 Chrome ウェブストア デベロッパー ダッシュボードのアクセス管理について詳しくは、こちらをご覧ください。
- グループ投稿者リストを更新したばかりの場合は、Chrome ウェブストア デベロッパー ダッシュボードでグループ投稿者メンバーシップ リストが同期されていることを確認します。パブリッシャーのメンバーシップ リストの同期について詳しくは、こちらをご覧ください。
App Check(iOS のみ)
App Check 機能は、Apple の App Attest サービスを使用して、Google OAuth 2.0 エンドポイントに対するリクエストが正規のアプリから発信されたものであることを確認することで、iOS アプリを不正使用から保護します。これにより、アプリのなりすましのリスクを軽減できます。
iOS クライアントで App Check を有効にする
iOS クライアントで App Check を有効にするには、次の要件を満たす必要があります。- iOS クライアントのチーム ID を指定する必要があります。
- バンドル ID にはワイルドカードを使用しないでください。複数のアプリに解決される可能性があるためです。つまり、バンドル ID にはアスタリスク(*)記号を含めないでください。
App Check を有効にすると、OAuth クライアントの編集ビューに、クライアントからの OAuth リクエストに関連する指標が表示されるようになります。App Check を適用するまで、未確認のソースからのリクエストはブロックされません。指標モニタリング ページの情報は、強制適用を開始するタイミングを判断するのに役立ちます。
iOS アプリで App Check を有効にすると、App Check 機能に関連するエラーが表示されることがあります。これらのエラーを解決するには、次の手順をお試しください。
- 指定したバンドル ID とチーム ID が有効であることを確認します。
- バンドル ID にワイルドカードを使用していないことを確認します。
iOS クライアントに App Check を適用する
アプリで App Check を有効にしても、認識できないリクエストが自動的にブロックされるわけではありません。この保護を適用するには、iOS クライアントの編集ビューに移動します。[Google Identity for iOS] セクションの右側に、App Check の指標が表示されます。指標には次の情報が含まれます。- 確認済みのリクエスト数 - 有効な App Check トークンを含むリクエスト。App Check の適用を有効にすると、このカテゴリのリクエストのみが成功します。
- 未検証のリクエスト数: 古いクライアント リクエストの可能性 - App Check トークンがないリクエスト。これらのリクエストは、App Check の実装が含まれていない古いバージョンのアプリから送信された可能性があります。
- 未検証のリクエスト数: 送信元が不明なリクエスト - App Check トークンがなく、アプリから送信されていないと思われるリクエスト。
- 未検証のリクエスト数: 無効なリクエスト - 無効な App Check トークンを含むリクエスト。お客様のアプリになりすまそうと試みている偽のクライアント、またはエミュレートされた環境からのものである可能性があります。
App Check を適用するには、[ENFORCE] ボタンをクリックして、選択内容を確定します。適用が有効になると、クライアントからの未検証のリクエストはすべて拒否されます。
注: 強制適用を有効にした後、変更が有効になるまでに最大 15 分かかることがあります。
iOS クライアントの App Check の適用を解除する
アプリの App Check の適用を解除すると、適用が停止し、クライアントから Google OAuth 2.0 エンドポイントへのすべてのリクエスト(未検証のリクエストを含む)が許可されます。
iOS クライアントの App Check を適用しないようにするには、iOS クライアントの編集ビューに移動して [適用しない] ボタンをクリックし、選択内容を確認します。
注: App Check の適用を解除した後、変更が反映されるまでに最長で 15 分ほどかかることがあります。
iOS クライアントの App Check を無効にする
アプリの App Check を無効にすると、すべての App Check モニタリングと適用が停止します。代わりに App Check の適用を解除して、クライアントの指標のモニタリングを続行することを検討してください。
iOS クライアントの App Check を無効にするには、iOS クライアントの編集ビューに移動し、[Firebase App Check を使用して OAuth クライアントを不正行為から保護する] 切り替えボタンをオフにします。
注: App Check を無効にした後、変更が反映されるまでに最大 15 分かかることがあります。
時間に基づくアクセス
時間ベースのアクセスでは、ユーザーはアクションを完了するために、アプリが期間限定でデータにアクセスすることを許可できます。時間ベースのアクセスは、同意フロー中に一部の Google サービスで利用できます。ユーザーは、限られた期間のみアクセスを許可するオプションを選択できます。たとえば、 Data Portability API を使用すると、データを 1 回だけ転送できます。
ユーザーがアプリに時間ベースのアクセス権を付与すると、更新トークンは指定された期間の経過後に期限切れになります。特定の状況下では、更新トークンが早期に無効になることがあります。詳しくは、こちらのケースをご覧ください。このような場合、認証コード交換レスポンスで返される refresh_token_expires_in フィールドは、更新トークンの有効期限が切れるまでの残り時間を表します。
関連情報
IETF のベスト カレント プラクティス OAuth 2.0 for Native Apps では、ここに記載されているベスト プラクティスの多くが確立されています。
クロスアカウント保護機能を実装する
ユーザーのアカウントを保護するために行うべき追加の手順として、Google のクロス アカウント保護サービスを利用してクロスアカウント保護機能を実装することが挙げられます。このサービスでは、ユーザー アカウントの大きな変更に関する情報をアプリケーションに提供するセキュリティ イベント通知を登録できます。この情報を使用して、イベントへの対応方法に応じてアクションを実行できます。
Google のクロスアカウント保護機能によってアプリに送信されるイベントタイプの例を次に示します。
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked -
https://schemas.openid.net/secevent/oauth/event-type/token-revoked -
https://schemas.openid.net/secevent/risc/event-type/account-disabled
クロスアカウント保護の実装方法と利用可能なイベントの完全なリストについては、 クロスアカウント保護機能でユーザー アカウントを保護する をご覧ください。