ガジェットのOAuth認証 その2
今回もGoogle Code の Gadget API のページを参考にしながらOAuthについて。
ガジェットで OAuth を利用するには、XMLに以下の情報を含める必要がある。
- サービスプロバイダ : OAuth による認証が可能な Web アプリケーション。
- エンドポイント : 個人データにアクセスする際のURL。
セクション : ガジェットで使用するあらゆるサービスとエンドポイントの詳細を指定。 セクション内に記述。 - ユーザがデータへのアクセスを承認したかを判別するプログラム。
- ユーザがアクセスを許可していない場合、ガジェットはユーザがサービスプロバイダにアクセスできる方法を提供する必要がある。
- 例) サービスプロバイダの OAuth 認証 URL を指すリンクをユーザに表示する。その後、サービスプロバイダの手順にしたがって、ユーザは認証と承認を行う。ユーザが自分のデータへのアクセスを承認すると、ガジェットはユーザのデータにアクセスできるようになる。
- makeRequest()関数の呼び出し。
- 取得したデータを処理するコード。
これを念頭に置きながら、前回の記事で動かしたサンプルガジェットのソースを読んでみる。
サンプルガジェットはユーザの連絡先を取得して表示するもの。
セクション
<?xml version="1.0" encoding="UTF-8" ?> <Module> <ModulePrefs title="OAuth Contacts" scrolling="true"> <Require feature="opensocial-0.8" /> <Require feature="locked-domain"/> <OAuth> <Service name="google"> <Access url="https://www.google.com/accounts/OAuthGetAccessToken" method="GET" /> <Request url="https://www.google.com/accounts/OAuthGetRequestToken?scope=http://www.google.com/m8/feeds/" method="GET" /> <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" /> </Service> </OAuth> </ModulePrefs>
: コンテナ(OAuth をサポートしている環境)と、ガジェットの OAuth サービス構成を記述する。 : name はサービスの名前。実行時にこれを使用して OAuth サービスを参照する。 、 : アクセストークンとリクエストトークンのURLを指定。また、 タグのscopeに連絡先を取得するためのエンドポイント(Google Data Contacts のドキュメントを参照)のURLを指定。ここでは、"http://www.google.com/m8/feeds/"とする。 : OAuth 認証 URL を指定。ガジェットがユーザデータにアクセスするのにそのユーザの承認を求める必要がある場合、この URL に対してポップアップウィンドウが開く。
Google の他のサービスからデータを取得する場合は、
データの取得
function fetchData() { var params = {}; url = "http://www.google.com/m8/feeds/contacts/default/base?alt=json"; params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON; params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.OAUTH; params[gadgets.io.RequestParameters.OAUTH_SERVICE_NAME] = "google"; params[gadgets.io.RequestParameters.OAUTH_USE_TOKEN] = "always"; params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET; gadgets.io.makeRequest(url, function (response) { if (response.oauthApprovalUrl) { // Create the popup handler. The onOpen function is called when the user // opens the popup window. The onClose function is called when the popup // window is closed. var popup = shindig.oauth.popup({ destination: response.oauthApprovalUrl, windowOptions: null, onOpen: function() { showOneSection('waiting'); }, onClose: function() { fetchData(); } }); // Use the popup handler to attach onclick handlers to UI elements. The // createOpenerOnClick() function returns an onclick handler to open the // popup window. The createApprovedOnClick function returns an onclick // handler that will close the popup window and attempt to fetch the user's // data again. var personalize = document.getElementById('personalize'); personalize.onclick = popup.createOpenerOnClick(); var approvaldone = document.getElementById('approvaldone'); approvaldone.onclick = popup.createApprovedOnClick(); showOneSection('approval'); } else if (response.data) { showOneSection('main'); showResults(response.data); } else { // The response.oauthError and response.oauthErrorText values may help debug // problems with your gadget. var main = document.getElementById('main'); var err = document.createTextNode('OAuth error: ' + response.oauthError + ': ' + response.oauthErrorText); main.appendChild(err); showOneSection('main'); } }, params); }
fetch()関数では、こちらの記事で書いた makeRequest()関数を呼び出す。
makeRequest()関数には url、callback、opt_params が必要だった。
- url : Google Data Contacts のエンドポイントのURLを指定。
- 以下のように、"?alt=json"と加えることでデータを JavaScript オブジェクトとして取得できる。
- url = "http://www.google.com/m8/feeds/contacts/default/base?alt=json";
- opt_params : OAuthに関するパラメータを記述。
- callback : 以下で説明。
callback では
- response.oauthApprovalUrl を見る。
- ユーザがユーザデータへのアクセスを許可していないとき、response.oauthApprovalUrl には URL が含まれる。
- ユーザはこの URL にアクセスして、ガジェットによるデータアクセスを許可する必要がある。
- ガジェットは、ポップアップウィンドウを管理するための shindig.oauth.popup オブジェクトを作成する。
- ユーザがリンクをクリックしてポップアップを開くときに、onOpen 関数が呼び出される。
- ガジェットは showOneSection('waiting') を呼び出して適切なメッセージを表示し、ユーザがアクセスを承認するまで待機する。
- ポップアップウィンドウを閉じるときに、onClose 関数が呼び出される。ポップアップウィンドウが閉じられると、ガジェットはユーザデータを取得するための fetchData() の呼び出しを登録する。
- 状況に応じて <div> の出力を変える。
認証に伴うガジェットへの表示
<div id="main" style="display: none"> </div> <div id="approval" style="display: none"> <img src="http://gadget-doc-examples.googlecode.com/svn/trunk/images/new.gif"> <a href="#" id="personalize">Personalize this gadget</a> </div> <div id="waiting" style="display: none"> Please click <a href="#" id="approvaldone">I've approved access</a> once you've approved access to your data. </div> <script type="text/javascript"> function showOneSection(toshow) { var sections = [ 'main', 'approval', 'waiting' ]; for (var i=0; i < sections.length; ++i) { var s = sections[i]; var el = document.getElementById(s); if (s === toshow) { el.style.display = "block"; } else { el.style.display = "none"; } } }
ガジェットは <div> と showOneSection() 関数を使い、ガジェットの承認状態に基づいて3つの <div> によって表示を変える。
- approval : ユーザがアクセスをまだ許可していない場合、ガジェットは approval <div> を使って、リクエストトークンを含む [Personalize this gadget] リンク付きの UI を表示する。ユーザはこのリンクをクリックして承認プロセスを開始する。
- waiting : ユーザがポップアップウィンドウを開いてアクセスを承認するまで、ガジェットはこの <div> を表示する。ガジェットは、ユーザがデータへのアクセスを承認したことに対して確認を求めるメッセージを表示する。ユーザがアクセスを承認したことをガジェットが自動で検出できれば、ユーザーがこのリンクをクリックしなくても済むようにできるが、このリンクを表示しておくと、ユーザは自動検出が失敗したときもデータをフェッチできるようになる。自動検出が失敗した場合、ガジェットは「Please click I've approved access once you've approved access to your data.」というメッセージを表示する。ユーザがこれをクリックすると、ガジェットは fetchData() を呼び出してユーザデータをフェッチする。
- main : アクセストークンが取得されると、ガジェットは実行されるたびに main <div> を使ってユーザデータを表示する。この <div> はエラーの表示にも使用される。
今回はGoogle Code の Gadget API のページをかなり引用してサンプルガジェットのソースを読んだ。
次回は、サンプルガジェットを元に、Google ドキュメントの一覧を表示するガジェットを作成する。