Google APIのAccess Tokenをお手軽に取得する

  • 184
    いいね
  • 10
    コメント
この記事は最終更新日から1年以上が経過しています。

Google APIの各種リソースに対する大抵の操作はREST風かつOAuth2なAPIになっていて、Access TokenとAPIのURLさえわかっていれば、例えば次のようにcurlコマンドを使って簡単にAPIを実行できます。

curl -H "Authorization: Bearer $ACCESS_TOKEN" $ENDPOINT

OAuth2はラクチンで助かりますね。ただここで必要となるAccess Tokenは OAuth2 Flow と呼ばれる手順を用いて取得する必要があり、そこを理解していない人が多そうに思いました。実はこちらもすごい簡単で、curlとブラウザだけで認可フローを実行できるのです。

TL;DR

環境変数の設定

CLIENT_ID=...
CLIENT_SECRET=...
REDIRECT_URI=urn:ietf:wg:oauth:2.0:oob
SCOPE=SCOPE1%20SCOPE2%20

認可画面のURLを組み立て、ブラウザで開く

echo "https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=$SCOPE&access_type=offline" 

ブラウザに表示されたAuthorization Codeを使ってAccess Tokenを取得する

AUTHORIZATION_CODE=...

curl --data "code=$AUTHORIZATION_CODE" --data "client_id=$CLIENT_ID" --data "client_secret=$CLIENT_SECRET" --data "redirect_uri=$REDIRECT_URI" --data "grant_type=authorization_code" --data "access_type=offline" https://www.googleapis.com/oauth2/v4/token

Refresh Tokenを使って新しいAccess Tokenを取得する

REFRESH_TOKEN=...

curl --data "refresh_token=$REFRESH_TOKEN" --data "client_id=$CLIENT_ID" --data "client_secret=$CLIENT_SECRET" --data "grant_type=refresh_token" https://www.googleapis.com/oauth2/v4/token

OAuth2 の認可フローの簡単な説明

登場人物は3者です。

  1. Google
  2. Application
  3. User(Browser)

認可フローは Google Identity Platformのリファレンスにも記述がありますが、Applicationの役割に注目すると、以下の二点を実装するだけです。

  1. Applicationが、ユーザの認可を得るためのページのURLをGoogleから取得し、Browserにリダイレクトとして送信する(Redirecting to Google's OAuth 2.0 server
  2. ユーザが認可することで生成されたAuthorization CodeをGoogleに渡して Access Token に交換してもらう(Handling the OAuth 2.0 server response

CLIでの手順

Client IDの生成

Developer ConsoleのAPI Managerで、ClientIDを作成する必要があります。

  1. New Credentials から OAuth2 client ID を選択する。
    Screen Shot 2016-01-31 at 18.17.47.png

  2. Application typeで Other を選択する。
    Screen Shot 2016-01-31 at 18.17.38.png

Application Typeは「認可フロー(Access Tokenを取得するフロー)」の方法であって、APIを叩くときには関係ありません。よくあるのはWeb Applicationですが、Otherを選ぶとout of bandという種類で、いわゆるDesktop Client用のフローを選択した事になります。Web Applicationでいうredirect_uiの値は固定値urn:ietf:wg:oauth:2.0:oobを使用することになります。

Scopeの調査

使用するAPIのリファレンスを探し当て、リファレンスの"Auth" というキーワードと"Scope"というキーワードを調べるとすぐにわかります。例えばGoogle Drive APIであればhttps://www.googleapis.com/auth/driveという値です。

認可画面のURLを取得する

まずは以下のように環境変数を設定します。SCOPEに複数の値を設定する場合は 空白文字で連結する必要があるので、空白文字をURLエンコードした値 %20 で連結しましょう。

CLIENT_ID=...
CLIENT_SECRET=...
REDIRECT_URI=urn:ietf:wg:oauth:2.0:oob
SCOPE=SCOPE1%20SCOPE2%20

認可画面のURLを取得する…のはブラウザにまかせて、「認可画面のURLを返すENDPOINThttps://accounts.google.com/o/oauth2/v2/auth」へのパラメータを組み立てて、そのままブラウザで開きます。
ここで組み立てたURLにアクセスすると、302が返されそのLocationヘッダの中身が「認可画面のURL」なんですが、302はそのままブラウザ任せで処理してもらうということです。

echo "https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=$SCOPE&access_type=offline" 

ここでは、Refresh Tokenも取得するためにaccess_type=offlineも指定しています。このURLをブラウザで開くと認可画面が表示されるので、AcceptしてやるとAuthorization Codeが表示されます。

Authorization CodeをAccess Tokenに交換する

先の手順で取得したAuthorization Codeを環境変数に設定し、https://www.googleapis.com/oauth2/v4/token を叩いてやります。

AUTHORIZATION_CODE=...

curl --data "code=$AUTHORIZATION_CODE" --data "client_id=$CLIENT_ID" --data "client_secret=$CLIENT_SECRET" --data "redirect_uri=$REDIRECT_URI" --data "grant_type=authorization_code" --data "access_type=offline" https://www.googleapis.com/oauth2/v4/token

これでAccess Token, Refresh Token等を取得できます。SCOPEにopenid email profileを追加してやれば、OpenID Connectで使う id_token も取得できます。

おまけ:

Refresh TokenをAccess Tokenに交換する

Access Tokenは有効期限がありますが、Refresh Tokenを保存しておけばいつでも(明示的にrevokeするまでは)新しいAccess Tokenを取得できます。

REFRESH_TOKEN=...

curl --data "refresh_token=$REFRESH_TOKEN" --data "client_id=$CLIENT_ID" --data "client_secret=$CLIENT_SECRET" --data "grant_type=refresh_token" https://www.googleapis.com/oauth2/v4/token

Refresh TokenやAccess Tokenを使ってRevokeする

curl https://accounts.google.com/o/oauth2/revoke?token=...

tokenに指定する値は、Refresh Token, Access TokenどちらでもOKです。

Access Tokenの状態を確認する

curl "https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=$ACCESS_TOKEN"

このAPIでAccess Tokenの有効期限や、認可されたSCOPEが取得できます。

なお、SCOPEが足りない(認可されていないリソース)へアクセスしようとした場合は 403 Insufficient Permission というエラーが返されて403の原因が少しわかりにくいので、原因不明の403を受けた場合はこのAPIを試すと良いです。
一方、同じく403ではありますが、Projectで有効にしていないAPIを叩いた場合はAccess Not Configured. The API (Notes API) is not enabled for your project...というわかりやすいエラーが返されます。