前回の記事ではGoogle Apps Scriptを使ってWebアプリケーションを作成する手順を紹介しましたが、今回はWebアプリケーションからOAuth認証(2.0)が必要なWeb APIを利用する方法を紹介します(例:Google URL Shortener API)。
- Webアプリケーションとしてスクリプトを作成し、ウェブ アプリケーションのURL(ここではテスト用)を取得します(「[Google Apps Script]Webアプリケーションを作成する。」参照)。
- ウェブ アプリケーションのURLの末尾を「/usercallback」に書き換えたものをリダイレクト先のURLとして控えておきます。
- API コンソールにアクセスします。
- 「Services」から利用するAPIを「ON」にします(ここではURL Shortener API)。
- 「API Access」から「Create an OAuth 2.0 client ID…」ボタンをクリックします。
- Branding Information画面が表示されたら必要事項(ここではProduct name:のみ)を入力後、「Next」ボタンをクリックします。
- Client ID Settings画面が表示されたら「Web application」を選択します。
- 「(more options)」をクリックし、「Authorized Redirect URIs」欄に手順2.で用意したリダイレクト先のURLを入力します。
- 「Authorized JavaScript Origins」欄には「https://script.google.com」と入力し、「Create client ID」ボタンをクリックします。
- API Access画面に作成したClient IDやClient secretが表示されるので、これらをメモ帳にでも控えておきます。
- コード.gsに下記コードを貼り付け、Client IDとClient secret、リダイレクト先のURLを設定します。
- 「doGet」関数を実行します。
- 「承認が必要です」とのメッセージが表示されたら「続行」ボタンをクリックします。
- 「このアプリが次の許可をリクエストしています。」とのメッセージが表示されたら「承認する」ボタンをクリックします。
- 手順1.で取得したアプリケーションのURLにアクセスして動作確認を行います。
- 「認証」リンクをクリックすると「このアプリが次の許可をリクエストしています。」とのメッセージが表示されるので(OAuth認証画面)、「承認する」ボタンをクリックします。
- 問題無く認証が行われれば、アクセストークン(Access Token)を取得することができ、OAuth認証が必要なAPIを利用することができます。
※ まずはアプリの準備を行います。
https://script.google.com/macros/s/EFGH/dev
↓
https://script.google.com/macros/s/EFGH/usercallback
※ Google APIの準備を行います。
※ 再びスクリプト エディタでの作業に戻ります。
var client_id = ''; //クライアントID(Client ID) var client_secret = ''; //クライアントシークレット(Client secret) var redirect_uri = ''; //リダイレクト先のURL var scope = 'https://www.googleapis.com/auth/urlshortener'; //APIによって要変更 function doGet(){ var url = 'https://accounts.google.com/o/oauth2/auth?client_id=' + client_id; url += '&redirect_uri=' + encodeURIComponent(redirect_uri); url += '&scope=' + encodeURIComponent(scope); url += '&state=' + ScriptApp.newStateToken().withMethod('callback').withArgument('name', 'value').withTimeout(2000).createToken(); url += '&response_type=code'; url += '&access_type=offline'; return HtmlService.createHtmlOutput('<a href="' + url + '">認証</a>'); } function callback(e){ //---------- Access Token取得ここから ---------- var opt = { "method" : "POST", "payload" : { "code" : e.parameter.code, "client_id" : client_id, "client_secret" : client_secret, "redirect_uri" :redirect_uri, "grant_type" : "authorization_code" }, "muteHttpExceptions" : true }; var res = UrlFetchApp.fetch('https://accounts.google.com/o/oauth2/token', opt); var dat = JSON.parse(res.getContentText()); var access_token = dat.access_token; //---------- Access Token取得ここまで ---------- //---------- API使用例ここから ---------- opt = { "method" : "GET", "headers" : { "Authorization": "Bearer " + access_token } }; res = UrlFetchApp.fetch('https://www.googleapis.com/urlshortener/v1/url/history', opt); //---------- API使用例ここまで ---------- return HtmlService.createHtmlOutput('<pre>' + res.getContentText() + '</pre>'); }
doGet関数で認証画面へのリンク作成。
↓
認証画面で認証を行い、ページがリダイレクトされるとcallback関数が実行される。
↓
callback関数の中でアクセストークンを取得し、Web APIを利用した処理を実行する。
といった処理の流れになっています。
要するに、ScriptApp.newStateToken()を使って/usercallbackにstateパラメータを渡すとコールバック処理でいろいろできる、ということのようです。
今回のコードをテストするにあたって、下記Webページ、特に「GoogleAppsScript – Google Apps Script DE OAuth2 ~ GASで直接触れない Google APIを叩いてみるお~」がとても参考になりました。
■ 参考Webページ
・GoogleAppsScript – Google Apps Script DE OAuth2 ~ GASで直接触れない Google APIを叩いてみるお~ – Qiita
http://qiita.com/soundTricker/items/b4df3072088fcbd0e36d
・天使やカイザーと呼ばれて ≫ OAuth2.0によるGoogle+ APIのアクセス方法
http://www.eisbahn.jp/yoichiro/2011/10/oauth2-0_google-api.html
・Using OAuth 2.0 for Web Server Applications – Google Accounts Authentication and Authorization – Google Developers
https://developers.google.com/accounts/docs/OAuth2WebServer?hl=ja
・Getting Started – URL Shortener API – Google Developers
https://developers.google.com/url-shortener/v1/getting_started?hl=ja
・newStateToken()
https://developers.google.com/apps-script/reference/script/script-app?hl=ja#newStateToken%28%29
・Class StateTokenBuilder
https://developers.google.com/apps-script/reference/script/state-token-builder?hl=ja
【編集後記】
今回のコード、実はテスト時にまったく上手く行きませんでした。
authorization codeをPOSTするときにredirect_uriをURLエンコードしてしまったことが原因だったのですが、これに気付くまで大分時間が掛かりました。
コードはよく見ないとダメですね・・・。
この記事へのコメントはありません。