箱のプログラミング日記。

えんじにあ奮闘記

【Google APIs】OAuth2.0を使って認証を通す

f:id:y_hakoiri:20191102121915j:plain

Google APIsの使用にあたりOAuth2.0を使って認証を通すまでの過程をメモ。

前提知識がなさすぎて全体像を把握するまでに相当時間がかかってしまったのと、あちこちに散らばっているドキュメントをつなぎ合わせつつ理解するのがめちゃくちゃしんどかったのでわかりやすくまとめる。

前提

「Google APIs」はGoogleが提供している様々なサービスのAPIの総称で、どのサービスと連携させたいかによりどのAPIを使うべきかが異なる。

例えば、Googleカレンダーと連携したいなら「Google Calendar API」、Googleアナリティクスと連携したいなら「Google Analytics API」など。一つのサービスの特定の機能ごとにAPIが分かれている場合もある。

この「どのAPIを使うか」によって、OAuth2.0を使って認証をすべきものと必要ないものがあるため(詳しくは後述)、そもそも自分が使いたいAPIがOAuth2.0による認証が必要かどうかを調べるところから始まる。→APIの公式ドキュメントのQuickStartに大体載っていると思います。

(たったこれだけのことを理解するまでに数時間かかった)

できること

「OAuth2.0を使った認証」で何ができるかというと、クライアントから特定のAPIを使用するための認証を通すことができる。

ここでいうクライアントはAPIリクエストを叩くクライアントのことで、自作のアプリケーションや自分が開発に携わっているプロジェクトなどが当てはまると思います。

あくまでも、今回使いたいAPIを使うための認証を通すだけなので、準備段階。APIを使ってどうこうするのはまたその先の話であることに注意。

やること

ざっくり分けてやることは以下

  • API Consoleでプロジェクトを作成
  • 作成したプロジェクトにAPIを紐付ける
  • 使いたいAPIに合わせて認証情報を作成する
    • OAuth同意画面の作成
    • 認証情報の作成
  • 作成した認証情報を元にリフレッシュトークンを取得
    • コードパラメーターを取得
    • リフレッシュトークンを取得

一つずつ解説していきます

API Consoleでプロジェクトを作成

API Consoleを開くとこの辺りにデフォルトのプロジェクトが出てくると思うので、「▼」をクリック

project_pulldown

プロジェクト一覧がポップアップで出てくるので、右上の「新しいプロジェクト」をクリックして、新しいプロジェクトを作成

project_lists

create_project

プロジェクト名はコンソール上で確認するためのものなのでなんでも良いと思います。

作成したプロジェクトにAPIを紐付ける

プロジェクトが作成できたら自分が使いたいAPIを紐付けます。

先ほど作成したプロジェクトが選択されていることを確認して、「APIとサービスの有効化」をクリック

add_api

そうするとAPIライブラリに遷移するので、自分が使いたいAPIを検索して有効化する。

今回私はGoogle広告のAPI「Google Ads API」を使いたかったのでこちらを選択しました。

APIの有効化が完了すると、プロジェクトのダッシュボードで現在紐づいているAPIが表示されるようになる

api_console

ちなみに、APIの有効化はプロジェクト単位で行うので、もし別のプロジェクトを作成するならまた逐一有効化して紐付ける必要があります。

APIに合わせて認証情報を作成する

次にAPIの利用に必要な認証情報を作成します。

サイドバーもしくはプロジェクトの概要画面から「認証情報を作成」をクリックするとまず以下のような画面になるので、それぞれ選択

使用するAPI...先ほどプロジェクトに有効化したAPIがプルダウンで出てくるので選択

APIを呼び出す場所...今回はwebアプリケーションを格納しているサーバーから呼び出すので「サーバー」を選択

アクセスするデータの種類...APIの利用サービスによる。例えばGoogleMapとかだと特定のユーザーの認証は不要だけど、今回のようにGoogle広告などそのサービスを利用するアカウントが保有するデータにアクセスしたい場合は「ユーザーデータ」を選択

この状態で次に進もうとすると「同意画面を作成せよ」と出てくる。先に同意画面を作らないと認証情報の作成ができないので、ここで作っておく

OAuth同意画面の作成

次にエンドユーザー向けの同意画面を作成する。下のような画面になるので右側のガイドを参考に必須項目を埋めていく。

ドメインに関する項目もあるけど全てスルーで大丈夫でした。

その後、画面を進んでいくと「スコープ」「テストユーザー」など色々な項目が出てくるけど全部スルーでOK

※2021/2/28追記

APIを呼び出すアプリケーションを審査に出すまではテストユーザーでしかAPI呼び出しの同意ができない。

なので審査を出す前のテスト段階で、API Consoleを作成しているGoogleアカウント以外のアカウントから同意を得たい場合はここでテストユーザーに追加しておく。

認証情報の作成

同意画面が作成できたらまた認証情報の作成に戻る。

今回は上から2番目の「OAuth クライアントID」を選択

(ここで出てくる3種類の区別は下記の記事にお世話になりました。ありがとうございます)

RubyからGoogle APIにアクセスするのは半端なくめんどくさい - Qiita

次にこんな画面になるので、必須項目の「アプリケーションの種類」「名前」に加えて「承認済みのリダイレクト URI」を入力する

ここの「承認済みのリダイレクト URI」はこのあと出てくるリフレッシュトークンを取得するために必要。ただしURLはなんでも良い(詳しくは後述)のでlocalhostで登録する人が多い印象。

作成が完了すると一覧画面で認証情報が確認できる。認証情報は一番右のダウンロードボタンよりjsonファイルで取り込みができるのでダウンロードしておく。(この後の作業で中の情報を使う)

※2021/04/18追記 jsonファイルをDLしなくても右端の鉛筆マークから何回でも確認できるのでこっちの方が便利でした。

作成した認証情報を元にリフレッシュトークンを取得

ダウンロードした認証情報はこんな感じになっている

client_secret_hoge.com.json

{"web": 
{"client_id":"**********************",
"project_id":"************************",
"auth_uri":"https://accounts.google.com/o/oauth2/auth",
"token_uri":"https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
"client_secret":"********************",
"redirect_uris":["http://localhost"]}}

これを元にリフレッシュトークンを取得する。

そもそもリフレッシュトークンって何なん?って感じだったのだが、APIを直接動かすアクセストークンとは別で、アクセストークンには有効期限が設定されており、一定期間ごとに消滅するんだとか。

アクセストークンの有効期限が切れている場合は都度再発行が必要なのだけど、リフレッシュトークンを取得しておけばそれを元にリクエスト元を特定→新しいアクセストークンを発行してくれる模様。

というわけで、リフレッシュトークンは使い回すもの。リフレッシュトークンを取得するプロセスは最初の一回のみ(APIで動かしたいユーザーが複数いるならそのユーザーごとに一回ずつ)。これを理解するまでに時間がかかってしまった。

そもそもOAuth2.0の基礎を理解せず入ってしまったのが間違いだったので、後から見つけて参考になったリンクをこちらに貼っておきます。

一番分かりやすい OAuth の説明 - Qiita

コードパラメーターを取得

リフレッシュトークンを取得する前にまずコードパラメーターなるものが必要になるので先に作業します。

↓のURLに先ほど取得したjson(認証情報)を当てはめてブラウザからアクセスすると、

https://accounts.google.com/o/oauth2/auth?client_id=********&redirect_uri=**********&scope=https://www.googleapis.com/auth/adwords&access_type=offline&response_type=code

(ここの「scope」は使用するAPIによって異なる)

先ほど作成した同意画面が出てくる。該当のGoogleアカウントを選択→同意→リダイレクトが走る

ここでは認証情報を作成したときの「承認済みのリダイレクト URI」にリダイレクトが走るようになっている。適当にlocalhostを指定したのでエラーになるものの、ここで必要なのはURLに付与されたcodeパラメーターなので問題なし。

このcodeパラメーターを控えておく。

リフレッシュトークンを取得

やっとこさリフレッシュトークンが取得できます。

以下のcurlコマンドに先ほどの認証情報+取得したcodeパラメーターの値を当てはめて実行する。

curl -d client_id=************ -d client_secret=*********** -d redirect_uri=************** -d grant_type=authorization_code -d code={さっき取得したcodeパラメーターの値} https://accounts.google.com/o/oauth2/token

すると以下のような結果が返ってくる

{
  "access_token": "***************",
  "expires_in": 3599,
  "refresh_token": "*********************",
  "scope": "https://www.googleapis.com/auth/adwords",
  "token_type": "Bearer"

このaccess_tokenに有効期限が設定されている。クライアントアプリケーションからAPIを呼び出すときは毎回リクエストにrefresh_tokenを含める必要があり、refresh_tokenと紐づいたaccess_tokenを利用してAPI認証を通過する

→正しくは「リクエストヘッダにアクセストークンを含める必要がある。アクセストークンを取得するためにリフレッシュトークンを使用する」でした。

まとめ

長い道のりでしたがこんな感じです。

まだやっとAPIの初回の認証が通ったのみで実際にAPIを動かすのはここから...。すでに疲れた...。

参考

Product Overview  |  Google Ads API  |  Google Developers

RubyからGoogle APIにアクセスするのは半端なくめんどくさい - Qiita

GoogleAPIのアクセストークンとリフレッシュトークン - Qiita

Google API OAuth2.0のアクセストークン&リフレッシュトークン取得手順 2017年2月版 - Qiita