Google Chrome 拡張機能でOAuthを利用する方法
記事について
GoogleカレンダーAPIを使って拡張機能を作りたかったけど、OAuthでの認証が必要と分かった。色々調べていると認証が通ったので、そのメモ書き。
拡張機能でOAuthを利用する際に問題になること
- CONSUMER_KEYやCONSUMER_SECRETを公開してしまうこと
- 認証の際に別URLへコールバックされること
1に関して。
Googleのカレンダーやコンタクトや何やらのGoogle Data APIを叩きたかったら、OAuthで認証する必要がある。OAuthは通常CONSUMER_KEYやCONSUMER_SECRETをサービス提供側が事前に取得する必要がある。この2つのキーは他人に公開すると悪用される場合があるため、教えてはならない。
2に関して。
OAuthの仕様上、認証に必要なキーを取得するためにコールバックで別のURLを飛ばされてしまう。コールバックのURLにはhttp://* かhttps:// しか指定できず、Chrome拡張機能を示すchrome-extension://*は指定できない。
解決策
問題1の解決策は、CONSUMER_KEYとCONSUMER_SECRETに両方'anonymous'を入れるだけ。
問題2に関して。
Chrome APIのサンプルにOAuth機能を実現するサンプルが有る。Sample - OAuth Contacts
このサンプルを実行するとユーザのコンタクト情報が取得できたことが分かる。今回はこの中の
3ファイルを利用する。これらのファイルは拡張機能でOAuthを実現するために必要なファイルである。chrome_ex_ouath.htmlはコールバック先のファイルである。内部でどういった動作をしているかはわからないので、解説はできない。
実装
以下のプログラムはGoogleカレンダーAPIを使い予定を登録するプログラムである。
まずmanifest.jsonにはこのように書く。
{ ... "background_page": "background.html", "permissions": [ "tabs", "http://www.google.com/calendar/feeds/*", "https://www.google.com/accounts/OAuthGetRequestToken", "https://www.google.com/accounts/OAuthAuthorizeToken", "https://www.google.com/accounts/OAuthGetAccessToken" ], ... }
background.htmlで認証処理を行わせる。認証の際にドメインを複数またぐので、その許可を求める。
今回はGoogleのOAuth認証を行うのでそれ用の設定をしたが、Twitterに関しては別の方が書かれていた。Loading...
background.htmlで行わせる処理。
... <script src="OAuthSimple/chrome_ex_oauth.js"></script> <script src="OAuthSimple/chrome_ex_oauthsimple.js"></script> <script> var oauth = ChromeExOAuth.initBackgroundPage({ 'request_url' : 'https://www.google.com/accounts/OAuthGetRequestToken', 'authorize_url' : 'https://www.google.com/accounts/OAuthAuthorizeToken', 'access_url' : 'https://www.google.com/accounts/OAuthGetAccessToken', 'consumer_key' : 'anonymous', 'consumer_secret' : 'anonymous', 'scope' : 'http://www.google.com/calendar/feeds/', 'app_name' : 'Application Name' }); window.chromeExOAuth.callback_page = 'OAuthSimple/chrome_ex_oauth.html'; oauth.authorize(function() { var url = "http://www.google.com/calendar/feeds/default/private/full"; var body = JSON.stringify({ "data": { "title": "Tennis with Beth", "details": "Meet for a quick lesson.", "transparency": "opaque", "status": "confirmed", "location": "Rolling Lawn Courts", "when": [ { "start": "2010-04-17T15:00:00.000Z", "end": "2010-04-17T17:00:00.000Z" } ] } }); oauth.sendSignedRequest(url, function(text, xhr) { console.log(text); }, { 'method': 'POST', 'headers': {'GData-Version': '2', 'Content-Type': 'application/json'}, 'body': body }); }); ... </script> ...
ChromeのOAuthサンプルのファイルを読み込ませる。その後に、ChromeExOAuth.initBackgroundPage APIを使い認証の設定させる。問題1の解決策で書いたようにconsumer_keyとconsumer_secretに'anonymous'を入れる。
次の行に関してだが、これはコールバックURLの変更する手続きである。コールバックURLのデフォルトは'chrome_ex_oauth.html'となっている。変更するオプションも同APIに存在するが、変更出来なかった。chrome_ex_oauth.jsの関係するコードを読むと設定方法が分かった。windos.chromeExOAuth.callback_pageに任意のコールバックURLを入れることで設定ができた。
oauth.authorizeで認証を行わせる。引数の関数はtokenが取得できた時に呼ばれる関数である。ここで初めて、GoogleカレンダーAPIを使い予定を登録したり取得することが可能となる。
最後にGoogle カレンダーAPIを使い予定を登録する。そのためのAPIはこれ。POSTメソッドを使い予定を送信する。この時JSONフォーマットで送るので
Content-Type: application/json GData-Version: 2
とした。このヘッダ情報に加えてGoogle Data APIのバージョンも追加しておいた。今回のプログラムではバージョン情報を追加しなくとも動くことが確認できた。
これらの情報を送信するAPIはoauth.sendSignedRequestである。引数はそれぞれ、APIのURL、送信後のレスポンスを受け取る関数、送信情報である。