前回の記事では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エンコードしてしまったことが原因だったのですが、これに気付くまで大分時間が掛かりました。
コードはよく見ないとダメですね・・・。






























この記事へのコメントはありません。