Aikの技術日記

技術的な進捗とか成果とかを細々と投稿するブログです。時々雑記も。

Google系APIにてOAuth認証形式でAccessTokenを取得するまで

はじめに

こんにちは、筆者です。

先日、Youtube Data APIを使ってYoutube上のデータを取得する方法についてまとめましたが…。
aik0aaat.hatenadiary.jp

流石にYoutube Data APIから取れるデータだけでは、分析データとして足りなかったので。
Youtube Analytics APIにも手を出したのですが…。

こちら、OAuth認証が必須となるAPIでして…おまけに公式が提供しているフローが少しわかりづらく、
APIに必要な「AccessToken」取得周りに非常に難儀してしまい。

苦労したことを忘れない様に、備忘録として残しておこうと思う次第です。
同じく困っている人の参考になれば幸いです…。

それではいきましょう。

全体の流れ・前提知識

まず、AccessTokenを取得するまでの全体の流れから。

  1. GoogleCloudConsoleから、クライアントIDを入手
  2. Google Identity ServicesとクライアントIDを使用し、アクセストークン取得
    • 方法が2通りあり「認証コードフロー」と「暗黙的フロー(直接アクセストークン取得)」に分かれる

なお、このOAuth認証の処理は「Youtube Analytics API」に限らず、Googleが提供しているすべてのAPIにて共通となっています。

GmailやGoogleDriveなど、GoogleさんはたくさんのAPIを提供されてますが…。
今回の処理フローをマスターできれば、この辺のAPIの認証処理も同じ様にできるので、マスターできれば色んなところで流用できますぞっ!

お次は1.の「クライアントIDの入手方法」について見ていきましょう。

クライアントIDの入手

クライアントIDはGoogleCloudConsole上で取得できます。

GoogleCloudConsoleから任意のプロジェクトを選び、「APIとサービス」から「認証情報」を選び…。
「認証情報を作成」画面より、「OAuthクライアントID」を選択します、が…。 GoogleCloudConsole>APIとサービス画面

…新規に作ったプロジェクトであれば、
「OAuth同意画面を設定してね」という表示になると思います。 GoogleCloudConsole>OAuthクライアントID発行画面

ここでクライアントIDとは何かを少し話しましょう。
クライアントIDは噛み砕いていうと、「GoogleのOAuthサーバー上で、認証を処理するOAuthアプリの識別子」のことです。

OAuth認証を行うと、Googleのログインポップアップが開きログインすると思いますが…。
「ログイン後にどのOAuthアプリに対して認証を付与するか」をGoogle側が識別するためのID、と思えばいいかと。

GoogleCloudConsoleのプロジェクト1つにつき、このOAuthアプリを1つ設定できるのですが…。
新規作成したプロジェクトでは、そのOAuthアプリの設定がないのでこの様にBANされちゃうということです。

OAuth同意画面の設定 - UserType設定

なのでまずは、当プロジェクトのOAuthアプリ設定…「OAuth同意画面」の設定をしましょう。
GoogleCloudConsoleから任意のプロジェクトを選び、「APIとサービス」から「OAuth同意画面」へ移動します。 GoogleCloudConsole>OAuth同意画面

UserTypeを「内部」に設定すると、プロジェクト管理者が所属するWorkspace内のユーザーのみが使用できる様にできますが…。
プロジェクト管理者がGoogle Workspaceに加入しているユーザーでないなら「外部」のみしか選べません。 どちらか好きな方を選び、作成ボタンを押しましょう。

OAuth同意画面の設定 - アプリのUI設定

すると「アプリ登録の編集」画面に移行します。 GoogleCloudConsole>OAuth同意画面>アプリ登録の編集

ここではOAuth認証をするエンドユーザー側から見た、認証画面のUI設定が可能です。
各プロパティが何に紐づいているかは、右のガイドを見れば分かりやすいです。
((こういうところが親切なのは流石Googleさんですね…。

自分用にしか使わないのであれば適当で構わないですが、
もし一般公開を考えているサービスなら、ここの設定はしっかりした方がエンドユーザーへ安心感を与えられるかと。

設定を入力したら「保存して次へ」ボタンを押しましょう。
すると「スコープの設定画面」へ移行します。

OAuth同意画面の設定 - スコープ(権限)設定

スコープの設定画面はこんな感じ: GoogleCloudConsole>OAuth同意画面>スコープの設定画面

ここでは、OAuth認証時にアクセスできる権限を設定できます。
例えばここで「Youtube Analytics API」の権限を追加しておくと、エンドユーザーがOAuth認証をする際は以下の様に表示されます: エンドユーザー視点のスコープ付与画面

エンドユーザーに安心感を与えるためにも、必要以上の権限は追加せず使いたい最小限の権限を追加しておきましょう。

権限を追加するには、「スコープを追加または削除」ボタンを押せば追加できます。 GoogleCloudConsole>OAuth同意画面>スコープの設定画面>スコープ追加画面

注意として、↑のチェックボックス選択ウィンドウには「プロジェクトへ有効化したAPI」のものしか出ません。
例えばGoogleDriveのAPI権限を付与したいなら、「ライブラリ」タブからGoogleDriveのAPIを有効化しておきましょう。

ちなみに有効化せずとも、スコープ文字列(例:https://www.googleapis.com/auth/yt-analytics.readonly)がわかっているなら、手動追加も可能です。

設定を入力したら「保存して次へ」ボタンを押しましょう。
次で最後の設定項目となります。

OAuth同意画面の設定 - テストユーザー設定

次に「テストユーザー」設定画面に移行します。 GoogleCloudConsole>OAuth同意画面>テストユーザー設定画面

ここでOAuthアプリのステータスについてお話しすると…。
今作成しているOAuthアプリは、作成時点ではステータスは「テスト」というものになります。

この段階ではここで設定する「テストユーザー」しか、OAuth認証を行うことができません。
おまけにテストユーザーは100ユーザーしか追加できない制限も…。
また、OAuth認証時にエンドユーザーに下記の様な画面も出てしまいます。 エンドユーザー視点のテストアプリ警告画面

個人で使うならこのままで問題ないでしょうが、一般公開でこの制限はきついと思うので…。
「ユーザーの制限をなくし」「上記警告画面をなくしたい」場合はOAuthアプリを公開するため「Googleの確認」が必要になります。

筆者は個人利用前提でやってるので、Googleの確認を行う方法については当記事では触れませんのでご留意を…。

「テストユーザー」設定画面に話を戻すと、「ADD USERS」をクリックすることでユーザー追加画面へ移動します。 GoogleCloudConsole>OAuth同意画面>テストユーザー設定画面>ユーザー追加画面

GoogleアカウントのID…メールアドレスを指定すれば追加可能です。
追加したら「保存して次へ」を押しましょう。

最後に「概要」ページが開くので、今までの設定が適用されているかを確認します。
なおこの段階で保存はされているので、問題なければ画面を離れてOKです、お疲れ様でした!

クライアントIDの入手

これでようやくクライアントIDの入手が可能となります…やはりOAuth認証は大変ですね…。

APIとサービス」から「認証情報」を選び…。
「認証情報を作成」画面より、「OAuthクライアントID」を選択します。 GoogleCloudConsole>認証情報>OAuthクライアントID作成

先の時とは変わり、アプリケーションの種類を選べる画面になってるかと思います。
自分のユースケースに応じて、アプリケーションを選びましょう。
※当記事では「ウェブアプリケーション」を選択する前提で進めます GoogleCloudConsole>認証情報>OAuthクライアントID作成

任意のアプリケーションを選ぶと、アプリケーションの種類に応じて設定項目が表示されます。 GoogleCloudConsole>認証情報>OAuthクライアントID作成

「承認済みのJavaScript生成元」には、OAuth認証のリクエスト元URLを入れ、
承認済みのリダイレクトURIには、OAuth認証後に遷移するリクエスト先URLを入れましょう。

例えばhttp://localhost:8080/hogefugaからOAuth認証を行い、
認証後はhttp://localhost:8080/hogepiyoへリダイレクトするなら、
承認済みのJavaScript生成元、承認済みのリダイレクトURIどちらもhttp://localhosthttp://localhost:8080の2件を登録します。

入力後は「作成」ボタンを押しましょう。
すると、クライアントIDが記されたモーダルウィンドウが開きます。 GoogleCloudConsole>認証情報>OAuthクライアントID表示

※クライアントシークレットはサーバーサイドでリクエストする際に必要みたいですので、クライアントサイドJavaScript等でOAuth認証をするなら気にしなくてOKです

これでクライアントIDの取得は完了です、お疲れ様でした!
なお誤ってモーダルウィンドウを閉じても、詳細画面からクライアントIDは参照できるのでご安心を。

アクセストークン取得

ようやくクライアントIDをGetできたので…。
お次はこのクライアントIDを使って、アクセストークンを取得しましょう。

OAuth認証をするには幾つか方法がありますが:

今回は、3の「Identity Services JavaScript」を使うことにします。
この方法が最も新しく、公式Docsも他2つからの移行フローが出ていますからね…。

Google 3P Authorization JavaScript Library読み込み

まず、OAuth認証を使いたいWebページのHTMLファイルに以下を書き込みます:

<script src="https://accounts.google.com/gsi/client" onload="console.log('TODO: add onload function')">  
</script>

…もしnpm系統に明るい方なら「npmモジュールってないの?」と思われるかもしれませんが…。
なんと、当ライブラリはnpmモジュール対応してない様です…orz。

ただし型定義ファイルだけはあるみたいなので、
もしTypeScripterであればyarn add -D @types/google.accountsで型定義ファイルの導入は可能です。

ユーザー認証モデルの選択

お次はいよいよアクセストークンを取得するコードを書いていきます。
…が、この取得方法にも「暗黙的フロー」と「認証コードフロー」の2パターンあります…。
(至る所で選択肢があって迷いますね…)

暗黙的フローは、OAuth認証後直接アクセストークンを取得できる方法です。
ただし、有効期限が設定されており…デフォルトではリクエスト後、59分59秒までしか使えません。
個人利用ならこれで十分でしょうが、一般公開を考慮すると1時間ごとに認証要求はきついですね…。

認証コードフローは、OAuth認証後(Googleアカウントでログインしリダイレクトしてきた後)にアクセストークンではなく「コード」を受け取ります。
このコードを、Node.js等のサーバーサイドアプリケーション側で「アクセストークンへ変換して」使用する形式です。

正直言って手間がかかる方法ですが、コードには有効期限がなさそうなので…。
一回コードを受け取れれば、サーバーサイドで変換するだけでアクセストークンを受け取れるので便利そうです。

今回は処理が簡単な「暗黙的フロー」をベースに進めます。
認証コードフローについては、詳しくは公式Docsサンプルコードを参照ください: developers.google.com

暗黙的フロー(直接アクセストークン取得)の場合

JavaScriptに以下を記載し:

const tokenClient = google.accounts.oauth2.initTokenClient({
  client_id: "[取得したクライアントID]",
  scope: "[対象のスコープ、例:`https://www.googleapis.com/auth/yt-analytics.readonly`]", // スペース区切りで複数個のスコープを指定可能
  callback: (response) => {
    console.log(`AccessToken: ${response.access_token}`);
    console.log(response);
  },
  error_callback: (error) => {
    console.error("[Google OAuth認証]accessToken取得でエラーが発生しました。");
    console.error(error);
  },
});

HTMLに以下を記載すれば:

<button onclick="tokenClient.requestAccessToken()">
  Authorize with Google
</button>

ボタンを押し、OAuth認証後Console欄にAccessTokenが記されるはずです。
ここまでの道中が大変だったからか、コードの方は割と簡単にできますね…。

なおTypeScriptで型をきかせたい場合は、
npmモジュール@types/google.accountsをインストールのち、
以下をJS冒頭に記載してください。

/// <reference path="[node_modulesへのパス]/@types/google.accounts/index.d.ts" />

おわりに

今回は、GoogleAPIにてOAuth認証形式でAccessTokenを取得するまでのフローをご紹介しました。

やってみての感想としては…。
途中にも記載しましたが、OAuth認証してアクセストークンに至るまで、色んなフェーズで選択肢があるなという印象です…。

Googleというでかいプラットフォームで色々やるために、なのかなと思いますが…。
筆者の様に「サクッと作ってサクッと動かしたい」と思ってる層からすると、色々大変な思いをする羽目になりました。
((この大変な思いがブログを書こうとさせたきっかけでもあります…。

ただ、このやり方をマスターすればYoutubeだけでなく…。
GmailやGoogleDrive等、各種Googleが提供するAPIOAuth認証もできる様になると思えば、苦労する価値はあるかと思います。

当記事が筆者と同じ様に悩む方への参考になれば幸いです…。
それでは|д゚*)