Google OAuth 2.0 システムは、ウェブ アプリケーションと Google サービスの間のサーバー間のやり取りをサポートしています。このシナリオでは、個々のエンドユーザーではなく、アプリケーションに属するアカウントであるサービス アカウントが必要です。アプリケーションがサービス アカウントに代わって Google API を呼び出すため、ユーザーが直接関与することはありません。このシナリオは「2-legged OAuth」または「2LO」とも呼ばれます。(関連用語「3-legged OAuth」は、アプリケーションがエンドユーザーに代わって Google API を呼び出すシナリオで、ユーザーの同意が必要になる場合もあります)。
通常、アプリケーションは、ユーザーデータではなく Google API を使用して独自のデータを処理する際に、サービス アカウントを使用します。たとえば、データの永続性に Google Cloud Datastore を使用するアプリケーションでは、サービス アカウントを使用して Google Cloud Datastore API の呼び出しを認証します。
Google Workspace ドメイン管理者は、ユーザーの代わりにユーザーデータにアクセスするドメイン全体の権限をサービス アカウントに付与できます。
このドキュメントでは、Google API クライアント ライブラリ(推奨)または HTTP を使用して、アプリケーションがサーバー間の OAuth 2.0 フローを完了する方法について説明します。
概要
サーバー間のやり取りをサポートするには、まず API Consoleでプロジェクトのサービス アカウントを作成します。Google Workspace アカウントのユーザーのユーザーデータにアクセスする必要がある場合は、ドメイン全体へのアクセス権をサービス アカウントに付与します。
次に、アプリケーションはサービス アカウントの認証情報を使用して OAuth 2.0 認証サーバーからアクセス トークンをリクエストして、承認済みの API 呼び出しを行います。
最後に、アプリケーションは、アクセス トークンを使用して Google API を呼び出すことができます。
サービス アカウントの作成
サービス アカウントの認証情報には、生成された一意のメールアドレスと、少なくとも 1 つの公開鍵/秘密鍵のペアが含まれます。ドメイン全体の委任が有効になっている場合、クライアント ID はサービス アカウントの認証情報にも含まれます。
アプリケーションが Google App Engine で実行されている場合は、プロジェクトの作成時にサービス アカウントが自動的に作成されます。
アプリケーションが Google Compute Engine で実行されている場合は、プロジェクトの作成時にサービス アカウントも自動的に設定されますが、Google Compute Engine インスタンスの作成時にこのアプリケーションでアクセスする必要があるスコープを指定する必要があります。詳細については、サービス アカウントを使用するためのインスタンスの準備をご覧ください。
アプリケーションが Google App Engine または Google Compute Engine で実行されていない場合は、 Google API Consoleでこれらの認証情報を取得する必要があります。サービス アカウントの認証情報を生成するか、すでに生成されている公開認証情報を表示するには、次の操作を行います。
まず、サービス アカウントを作成します。
- Service accounts page開きます。
- If prompted, select a project, or create a new one.
- [サービス アカウントの作成] をクリックします。
- [サービス アカウントの詳細] で、サービス アカウントの名前、ID、説明を入力し、[作成して続行] をクリックします。
- オプション: [ Grant this service account access to project ] で、サービス アカウントに付与する IAM ロールを選択します。
- [続行]をクリックします。
- オプション: [ユーザーにこのサービス アカウントへのアクセスを許可する] で、サービス アカウントの使用と管理を許可するユーザーまたはグループを追加します。
- [完了]をクリックします。
次に、サービス アカウント キーを作成します。
- 作成したサービス アカウントのメール アドレスをクリックします。
- [キー] タブをクリックします。
- [キーの追加]ドロップダウン リストで、[新しいキーの作成]を選択します。
- [作成]をクリックします。
新しい公開鍵と秘密鍵のペアが生成され、マシンにダウンロードされます。秘密鍵の唯一のコピーとして機能します。あなたはそれを安全に保管する責任があります。このキー ペアを紛失した場合は、新しいキー ペアを生成する必要があります。
いつでも API Console に戻って、メールアドレス、公開鍵のフィンガープリント、その他の情報を表示したり、追加の公開鍵/秘密鍵のペアを生成したりできます。 API Consoleのサービス アカウント認証情報の詳細については、 API Consoleヘルプファイルのサービス アカウントをご覧ください。
サービス アカウントのメールアドレスをメモし、アプリケーションからアクセスできる場所にサービス アカウントの秘密鍵ファイルを保存します。これらは、アプリケーションで承認済みの API 呼び出しを行うために必要となります。
サービス アカウントにドメイン全体の権限を委任する
Google Workspace アカウントの Google Workspace アカウントの管理者は、アプリケーションが Google Workspace ドメインのユーザーに代わって Workspace のユーザーデータにアクセスすることを許可できます。たとえば、Google Calendar API を使用して Google Workspace ドメイン内のすべてのユーザーのカレンダーに予定を追加するアプリケーションでは、ユーザーの代わりにサービス アカウントを使用して Google Calendar API にアクセスします。ドメイン内でユーザーに代わってデータにアクセスすることをサービス アカウントに認可することは、サービス アカウントへの「ドメイン全体の権限の委任」と呼ばれることもあります。
サービス アカウントにドメイン全体の権限を委任するには、Google Workspace ドメインの特権管理者が次の手順を行います。
- Google Workspace ドメインの 管理コンソールから、メインメニュー > [セキュリティ] > [アクセスとデータ管理] > [API の制御] に移動します。
- [ドメイン全体の委任] ペインで、[ドメイン全体の委任を管理] を選択します。
- [新しく追加] をクリックします。
- [クライアント ID] フィールドに、サービス アカウントのクライアント ID を入力します。サービス アカウントのクライアント ID は Service accounts pageで確認できます。
- [OAuth スコープ(カンマ区切り)] フィールドに、アプリケーションへのアクセスを許可するスコープのリストを入力します。たとえば、アプリケーションがドメイン全体の Google Drive API と Google Calendar API に対する完全アクセス権を必要とする場合は、「https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar」と入力します。
- [Authorize] をクリックします。
これで、Workspace ドメインのユーザーとして(ユーザーになりすまし)API 呼び出しを行う権限がアプリケーションに付与されました。このような委任された API 呼び出しを行う準備をする際は、権限借用するユーザーを明示的に指定します。
委任された API 呼び出しの準備
Java
API Consoleからクライアントのメールアドレスと秘密鍵を取得したら、Java 用の Google API クライアント ライブラリを使用して、サービス アカウントの認証情報と、アプリケーションがアクセスする必要があるスコープから GoogleCredential
オブジェクトを作成します。次に例を示します。
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.services.sqladmin.SQLAdminScopes; // ... GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json")) .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));
Google Cloud Platform 上でアプリを開発する場合は、代わりにアプリケーションのデフォルト認証情報を使用できます。これにより、プロセスを簡素化できます。
ドメイン全体の権限の委任
サービス アカウントにドメイン全体のアクセス権を委任していて、ユーザー アカウントの権限を借用する場合は、GoogleCredential
オブジェクトの createDelegated
メソッドを使用してユーザー アカウントのメールアドレスを指定します。例:
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json")) .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN)) .createDelegated("workspace-user@example.com");
上記のコードでは、GoogleCredential
オブジェクトを使用して createDelegated()
メソッドを呼び出しています。createDelegated()
メソッドの引数は、Workspace アカウントに属するユーザーである必要があります。リクエストを作成するコードは、この認証情報を使用して、サービス アカウントを使用して Google API を呼び出します。
Python
API Consoleからクライアントのメールアドレスと秘密鍵を取得したら、Python 用 Google API クライアント ライブラリを使用して次の手順を行います。
- サービス アカウントの認証情報と、アプリケーションがアクセスする必要があるスコープから、
Credentials
オブジェクトを作成します。例:from google.oauth2 import service_account SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin'] SERVICE_ACCOUNT_FILE = '/path/to/service.json' credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=SCOPES)
Google Cloud Platform 上でアプリを開発する場合は、代わりにアプリケーションのデフォルト認証情報を使用できます。これにより、プロセスを簡素化できます。
- ドメイン全体の権限の委任
サービス アカウントにドメイン全体のアクセス権を委任していて、ユーザー アカウントの権限を借用する場合は、既存の
ServiceAccountCredentials
オブジェクトのwith_subject
メソッドを使用します。次に例を示します。delegated_credentials = credentials.with_subject('user@example.org')
アプリケーションで Credentials オブジェクトを使用して、Google API を呼び出します。
HTTP/REST
API Consoleからクライアント ID と秘密鍵を取得したら、アプリケーションで次の手順を行う必要があります。
- ヘッダー、クレームセット、署名を含む JSON ウェブトークン(JWT、発音、「jot」)を作成します。
- Google OAuth 2.0 認可サーバーからアクセス トークンをリクエストします。
- 承認サーバーが返す JSON レスポンスを処理します。
以降のセクションでは、これらの手順の実行方法について説明します。
レスポンスにアクセス トークンが含まれている場合は、アクセス トークンを使用して Google API を呼び出すことができます。(レスポンスにアクセス トークンが含まれていない場合、JWT とトークン リクエストが正しく構成されていないか、リクエストされたスコープにアクセスする権限がサービス アカウントに付与されていない可能性があります)。
アクセス トークンが期限切れになると、アプリケーションは別の JWT を生成し、署名して、別のアクセス トークンをリクエストします。

このセクションの残りの部分では、JWT の作成、JWT の署名、アクセス トークン リクエストの形成、レスポンスの処理の詳細について説明します。
JWT の作成
JWT は、ヘッダー、クレームセット、署名の 3 つの部分で構成されます。ヘッダーとクレームのセットは JSON オブジェクトです。これらの JSON オブジェクトは UTF-8 バイトにシリアル化され、Base64url エンコードでエンコードされます。このエンコードにより、エンコード処理が繰り返し行われるためエンコードが変更されても復元できるようになります。ヘッダー、クレームセット、署名は、ピリオド(.
)を使用して連結されます。
JWT は次のように構成されます。
{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}
署名のベース文字列は次のとおりです。
{Base64url encoded header}.{Base64url encoded claim set}
JWT ヘッダーの作成
ヘッダーは、署名アルゴリズム、アサーションの形式、JWT の署名に使用された [サービス アカウント キーのキー ID](https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys) を示す 3 つのフィールドで構成されます。アルゴリズムと形式は必須です。各フィールドの値は 1 つのみです。追加のアルゴリズムと形式が導入された時点で、このヘッダーは変更されます。鍵 ID はオプションです。誤った鍵 ID を指定すると、GCP はサービス アカウントに関連付けられているすべての鍵でトークンの検証を行い、有効な鍵が見つからない場合はトークンを拒否します。Google は将来的に、間違ったキー ID を持つトークンを拒否する権限を有します。
サービス アカウントは、RSA SHA-256 アルゴリズムと JWT トークン形式に依存しています。そのため、ヘッダーの JSON 表現は次のようになります。
{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}
これを Base64url で表現すると次のようになります。
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
JWT クレームセットを形成する
JWT クレームセットには、リクエストされている権限(スコープ)、トークンのターゲット、カード発行会社、トークンの発行時刻、トークンの有効期間など、JWT に関する情報が含まれています。ほとんどのフィールドは必須です。JWT ヘッダーと同様に、JWT クレームセットは JSON オブジェクトであり、署名の計算に使用されます。
必須クレーム
JWT クレームセットに必要なクレームを以下に示します。クレームセット内の任意の順序で表示される可能性があります。
名前 | 説明 |
---|---|
iss |
サービス アカウントのメールアドレス。 |
scope |
アプリがリクエストする権限のスペース区切りリストです。 |
aud |
アサーションの意図されたターゲットの記述子。アクセス トークン リクエストを使用する場合、この値は常に https://oauth2.googleapis.com/token になります。 |
exp |
アサーションの有効期限。1970 年 1 月 1 日 00:00:00 UTC からの経過秒数で指定します。この値は、発行時刻から最大 1 時間後に設定されます。 |
iat |
アサーションが発行された時刻。1970 年 1 月 1 日 00:00:00 UTC からの秒数で指定します。 |
JWT クレームセットの必須フィールドの JSON 表現を以下に示します。
{ "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com", "scope": "https://www.googleapis.com/auth/devstorage.read_only", "aud": "https://oauth2.googleapis.com/token", "exp": 1328554385, "iat": 1328550785 }
その他の申し立て
企業によっては、アプリケーションがドメイン全体の委任を使用して、組織内の特定のユーザーに代わって操作を行えます。アプリケーションがユーザーの権限を借用する前に、このような権限借用を行う権限が付与されている必要があり、通常は特権管理者によって処理されます。詳しくは、ドメイン全体の委任を使用して API のアクセスを制御するをご覧ください。
リソースへのアクセス権をアプリケーションで委任するアクセス トークンを取得するには、sub
フィールドの値として設定された JWT クレームにユーザーのメールアドレスを含めます。
名前 | 説明 |
---|---|
sub |
アプリケーションが委任されたアクセスをリクエストしているユーザーのメールアドレス。 |
アプリケーションにユーザーの権限借用がない場合、sub
フィールドを含むアクセス トークン リクエストに対するレスポンスはエラーになります。
sub
フィールドを含む JWT クレームセットの例を次に示します。
{ "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com", "sub": "some.user@example.com", "scope": "https://www.googleapis.com/auth/prediction", "aud": "https://oauth2.googleapis.com/token", "exp": 1328554385, "iat": 1328550785 }
JWT クレームセットをエンコードする
JWT ヘッダーと同様に、JWT クレームセットは UTF-8 および Base64URL セーフ エンコードでシリアル化される必要があります。以下に、JWT クレームセットの JSON 表現の例を示します。
{ "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com", "scope": "https://www.googleapis.com/auth/prediction", "aud": "https://oauth2.googleapis.com/token", "exp": 1328554385, "iat": 1328550785 }
署名の計算
JSON Web Signature(JWS)は、JWT の署名を生成するメカニズムをガイドする仕様です。署名の入力は、以下のコンテンツのバイト配列です。
{Base64url encoded header}.{Base64url encoded claim set}
署名を計算する際は、JWT ヘッダー内の署名アルゴリズムを使用する必要があります。Google OAuth 2.0 認可サーバーでサポートされている署名アルゴリズムは、SHA-256 ハッシュ アルゴリズムを使用した RSA のみです。これは、JWT ヘッダーの alg
フィールドで RS256
として表されます。
SHA256withRSA(SHASSA-PKCS1-V1_5-SIGN、SHA-256 ハッシュ関数とも呼ばれます)の Google API Consoleから取得した秘密鍵で、入力の UTF-8 表現に署名します。出力はバイト配列になります。
署名は Base64url でエンコードされている必要があります。ヘッダー、クレームセット、署名は、ピリオド(.
)を使用して連結されます。結果は JWT になります。わかりやすくするために、改行を入れています。
{Base64url encoded header}. {Base64url encoded claim set}. {Base64url encoded signature}
Base64url エンコード前の JWT の例を次に示します。
{"alg":"RS256","typ":"JWT"}. { "iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com", "scope":"https://www.googleapis.com/auth/prediction", "aud":"https://oauth2.googleapis.com/token", "exp":1328554385, "iat":1328550785 }. [signature bytes]
署名して送信の準備ができている JWT の例を次に示します。
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ
アクセス トークン リクエストの実行
署名付き JWT を生成したら、アプリケーションはそれを使用してアクセス トークンをリクエストできます。このアクセス トークン リクエストは HTTPS POST
リクエストであり、本文は URL エンコードされます。URL は以下のとおりです。
https://oauth2.googleapis.com/token
HTTPS POST
リクエストには、次のパラメータが必要です。
名前 | 説明 |
---|---|
grant_type |
必要に応じて、URL エンコードされた次の文字列を使用します。
urn:ietf:params:oauth:grant-type:jwt-bearer |
assertion |
JWT(署名を含む)。 |
アクセス トークン リクエストで使用される HTTPS POST
リクエストの未加工のダンプを次に示します。
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ
curl
を使用した同じリクエストを以下に示します。
curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU ' https://oauth2.googleapis.com/token
レスポンスの処理
JWT とアクセス トークンのリクエストが正しく構成されていて、サービス アカウントにオペレーションを実行する権限がある場合、認可サーバーからの JSON レスポンスにはアクセス トークンが含まれます。レスポンスの例を次に示します。
{ "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M", "scope": "https://www.googleapis.com/auth/prediction" "token_type": "Bearer", "expires_in": 3600 }
アクセス トークンは、expires_in
で指定された期間内で再利用できます。
Google API の呼び出し
Java
GoogleCredential
オブジェクトを使用して Google API を呼び出す手順は次のとおりです。
GoogleCredential
オブジェクトを使用して、呼び出す API のサービス オブジェクトを作成します。次に例を示します。SQLAdmin sqladmin = new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
- サービス オブジェクトによって提供されるインターフェースを使用して API サービスへのリクエストを行います。たとえば、ecommerce-example-123 プロジェクト内の Cloud SQL データベースのインスタンスを一覧表示するには、次のコマンドを実行します。
SQLAdmin.Instances.List instances = sqladmin.instances().list("exciting-example-123").execute();
Python
承認済みの Credentials
オブジェクトを使用して、次の手順で Google API を呼び出します。
- 呼び出す API のサービス オブジェクトを作成します。サービス オブジェクトを作成するには、API の名前と承認済みバージョンの
Credentials
オブジェクトを指定してbuild
関数を呼び出します。たとえば、Cloud SQL Administration API のバージョン 1beta3 を呼び出すには、次のようにします。import googleapiclient.discovery sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
- サービス オブジェクトによって提供されるインターフェースを使用して API サービスへのリクエストを行います。たとえば、ecommerce-example-123 プロジェクト内の Cloud SQL データベースのインスタンスを一覧表示するには、次のコマンドを実行します。
response = sqladmin.instances().list(project='exciting-example-123').execute()
HTTP/REST
アプリケーションがアクセス トークンを取得した後、その API で必要なアクセス スコープが付与されている場合は、そのトークンを使用して、特定のサービス アカウントまたはユーザー アカウントに代わって Google API を呼び出すことができます。これを行うには、access_token
クエリ パラメータまたは Authorization
HTTP ヘッダー Bearer
値を指定して、API のリクエストにアクセス トークンを含めます。可能であれば、HTTP ヘッダーの使用をおすすめします。クエリ文字列はサーバーログに表示されることが多いためです。ほとんどの場合、Google Drive の呼び出し(たとえば、Drive Files API を呼び出す)は、クライアント ライブラリを使用して設定できます。
すべての Google API を試して、そのスコープを OAuth 2.0 Playground で確認できます。
HTTP GET の例
Authorization: Bearer
HTTP ヘッダーを使用して
drive.files
エンドポイント(Drive Files API)を呼び出すと、次のようになります。独自のアクセス トークンを指定する必要があることに注意してください。
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
次に示すのは、access_token
クエリ文字列パラメータを使って認証済みユーザーの同じ API を呼び出す例です。
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
curl
の例
これらのコマンドは curl
コマンドライン アプリケーションでテストできます。HTTP ヘッダー オプションを使用した推奨の例を次に示します。
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
別の方法として、クエリ文字列パラメータ オプションを次のように使用することもできます。
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
アクセス トークンの有効期限が切れたとき
Google OAuth 2.0 認可サーバーによって発行されたアクセス トークンは、expires_in
で指定された期間が経過すると期限切れになります。アクセス トークンが期限切れになると、アプリケーションは別の JWT を生成し、署名して、別のアクセス トークンをリクエストする必要があります。
JWT エラーコード
error フィールド |
error_description フィールド |
意味 | 解決方法 |
---|---|---|---|
unauthorized_client |
Unauthorized client or scope in request. |
ドメイン全体の委任を使用する場合、ユーザーのドメインの管理コンソールでサービス アカウントが承認されません。 |
管理コンソールの [
ドメイン全体の委任] ページで、 通常、数分かかりますが、承認が Google アカウント内のすべてのユーザーに反映されるまで最大で 24 時間かかることがあります。 |
unauthorized_client |
Client is unauthorized to retrieve access tokens using this method, or client not
authorized for any of the scopes requested. |
サービス アカウントは、管理コンソールのクライアント ID(数値)ではなく、クライアント メールアドレスを使用して承認されました。 | 管理コンソールの [ ドメイン全体の委任] ページで、クライアントを削除し、数値 ID で再度追加します。 |
access_denied |
(任意の値) | ドメイン全体の委任を使用している場合、リクエストされた 1 つ以上のスコープが管理コンソールで承認されていません。 |
管理コンソールの [
ドメイン全体の委任] ページで、 通常、数分かかりますが、承認が Google アカウント内のすべてのユーザーに反映されるまで最大で 24 時間かかることがあります。 |
admin_policy_enforced |
(任意の値) | Google Workspace 管理者のポリシーにより、リクエストされた 1 つ以上のスコープを Google アカウントで承認できません。 |
管理者が OAuth クライアント ID に明示的にアクセス権が付与されるまで、すべてのスコープまたは機密性の高いスコープと制限付きスコープへのアクセスを制限する方法については、Google Workspace 管理者用ヘルプのヘルプ記事(Google Workspace のデータにアクセスできるサードパーティ製アプリと内部アプリを制御する)をご覧ください。 |
invalid_client |
(任意の値) |
OAuth クライアントまたは JWT トークンが無効であるか、正しく構成されていません。 詳細については、エラーの説明を参照してください。 |
JWT トークンが有効で、正しいクレームが含まれていることを確認してください。 OAuth クライアントとサービス アカウントが正しく構成され、正しいメールアドレスを使用していることを確認します。 JWT トークンが正しく、リクエストのクライアント ID に対して発行されていることを確認します。 |
invalid_grant |
Not a valid email. |
ユーザーが存在しません。 | sub 申請(フィールド)のメールアドレスが正しいことを確認します。 |
invalid_grant |
|
通常、これは現地システムの時刻が正しくないことを意味します。また、今後 exp の値が iat 値から 65 分を超えた場合、または exp 値が iat 値よりも低い場合にも発生することがあります。 |
JWT が生成されるシステムの時計が正しいことを確認します。必要に応じて、時刻を Google NTP と同期します。 |
invalid_grant |
Invalid JWT Signature. |
JWT アサーションが、クライアント メールアドレスで識別されたサービス アカウントに関連付けられていない秘密鍵で署名されているか、使用された鍵が削除、無効化、または期限切れされています。 また、JWT アサーションが正しくエンコードされていない場合は、Base64 でエンコードし、改行やパディングを同一にしてパディングしないでください。 |
JWT クレームセットをデコードし、アサーションに署名した鍵がサービス アカウントに関連付けられていることを確認します。 Google 提供の OAuth ライブラリを使用して、JWT が正しく生成されるようにしてください。 |
invalid_scope |
Invalid OAuth scope or ID token audience provided. |
スコープがリクエストされていない(スコープの空のリスト)か、リクエストされたスコープのいずれも存在しない(つまり、無効な)スコープです。 |
JWT の
|
disabled_client |
The OAuth client was disabled. |
JWT アサーションの署名に使用される鍵が無効になっています。 |
Google API Consoleに移動し、[IAM と管理] > [サービス アカウント] で、アサーションの署名に使用された「鍵 ID」を含むサービス アカウントを有効にします。 |
org_internal |
This client is restricted to users within its organization. |
リクエストの OAuth クライアント ID は、特定の Google Cloud 組織内の Google アカウントへのアクセスを制限するプロジェクトの一部です。 |
組織のサービス アカウントを使用して認証します。OAuth アプリケーションのユーザータイプの構成を確認します。 |
追加条項: OAuth を使用しないサービス アカウントの承認
一部の Google API では、OAuth 2.0 アクセス トークンではなく、署名された JWT を署名なしトークンとして直接使用して、承認済みの API 呼び出しを行うことができます。これにより、API 呼び出しを行う前に Google の承認サーバーにネットワーク リクエストを発行する必要がなくなります。
呼び出す API が Google API GitHub リポジトリで公開されているサービス定義を持っている場合、アクセス トークンの代わりに JWT を使用して承認済み API 呼び出しを行うことができます。手順は以下のとおりです。
- 上述のようにサービス アカウントを作成します。アカウントの作成時に取得した JSON ファイルを必ず保持してください。
- jwt.io にあるものなど、標準の JWT ライブラリを使用して、ヘッダーとペイロードを含む JWT を作成します。次に例を示します。
{ "alg": "RS256", "typ": "JWT", "kid": "abcdef1234567890" } . { "iss": "123456-compute@developer.gserviceaccount.com", "sub": "123456-compute@developer.gserviceaccount.com", "aud": "https://firestore.googleapis.com/", "iat": 1511900000, "exp": 1511903600 }
- ヘッダーの
kid
フィールドに、サービス アカウントの秘密鍵 ID を指定します。この値は、サービス アカウント JSON ファイルのprivate_key_id
フィールドで確認できます。 iss
フィールドとsub
フィールドには、サービス アカウントのメールアドレスを指定します。この値は、サービス アカウント JSON ファイルのclient_email
フィールドで確認できます。aud
フィールドに API エンドポイントを指定します。例:https://SERVICE.googleapis.com/
。iat
フィールドには、現在の Unix 時間を指定します。exp
フィールドには、JWT が期限切れになるちょうど 3,600 秒後の時刻を指定します。
サービス アカウントの JSON ファイルに含まれる秘密鍵を使用して、JWT を RSA-256 で署名します。
次に例を示します。
Java
google-api-java-client と java-jwt を使用する場合:
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json")); PrivateKey privateKey = credential.getServiceAccountPrivateKey(); String privateKeyId = credential.getServiceAccountPrivateKeyId(); long now = System.currentTimeMillis(); try { Algorithm algorithm = Algorithm.RSA256(null, privateKey); String signedJwt = JWT.create() .withKeyId(privateKeyId) .withIssuer("123456-compute@developer.gserviceaccount.com") .withSubject("123456-compute@developer.gserviceaccount.com") .withAudience("https://firestore.googleapis.com/") .withIssuedAt(new Date(now)) .withExpiresAt(new Date(now + 3600 * 1000L)) .sign(algorithm); } catch ...
Python
PyJWT を使用する場合:
iat = time.time() exp = iat + 3600 payload = {'iss': '123456-compute@developer.gserviceaccount.com', 'sub': '123456-compute@developer.gserviceaccount.com', 'aud': 'https://firestore.googleapis.com/', 'iat': iat, 'exp': exp} additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON} signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers, algorithm='RS256')
- 署名された JWT を署名なしトークンとして使用して、API を呼び出します。
GET /v1/projects/abc/databases/123/indexes HTTP/1.1 Authorization: Bearer SIGNED_JWT Host: firestore.googleapis.com