OAuthには、2legged OAuthなるものと、3legged OAuthなるものがあるらしい。
で、署名付きリクエストは、2legged OAuthというらしい。
2legged OAuthはHMACもRSAもやってみたので、次は3legged OAuthなるものをやってみる。
サービスプロバイダはGoogle。
サンプルとしてGoogle Contact(だっけ?)にアクセスして
自分で構築したShindig環境でアドレス張のデータを表示してみる。
おおきな作業の流れは以下な感じ。
1) ガジェットを用意
2) とりあえずShindigを動かして、該当するガジェット別のdomainを取得
3) google アカウントのManageDomainsページにアクセスし、2)で取得したドメインを登録
4) 3)で登録するとconsumer keyとconsumer secretが発行されるので、それをconfig/oauth.jsonへ記述。
5) ガジェットXMLの一部修正
6) shindigコンパイル&起動
でできるはず。
1) まずガジェットXMLを用意。
http://code.google.com/intl/ja/apis/gadgets/docs/oauth.html
のページを見ると、gadgetのサンプルXMLがあるので、それをコピペ。
- <?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>
- <Content type="html">
- <![CDATA[
- <!-- shindig oauth popup handling code -->
- <script src="http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/popup.js"></script>
- <style>
- #main {
- margin: 0px;
- padding: 0px;
- font-size: small;
- }
- </style>
- <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">
- // Display UI depending on OAuth access state of the gadget (see <divs> above).
- // If user hasn't approved access to data, provide a "Personalize this gadget" link
- // that contains the oauthApprovalUrl returned from makeRequest.
- //
- // If the user has opened the popup window but hasn't yet approved access, display
- // text prompting the user to confirm that s/he approved access to data. The user
- // may not ever need to click this link, if the gadget is able to automatically
- // detect when the user has approved access, but showing the link gives users
- // an option to fetch their data even if the automatic detection fails.
- //
- // When the user confirms access, the fetchData() function is invoked again to
- // obtain and display the user's data.
- 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";
- }
- }
- }
- // Process returned JSON feed to display data.
- function showResults(result) {
- showOneSection('main');
- var titleElement = document.createElement('div');
- var nameNode = document.createTextNode(result.feed.title.$t);
- titleElement.appendChild(nameNode);
- document.getElementById("main").appendChild(titleElement);
- document.getElementById("main").appendChild(document.createElement("br"));
- list = result.feed.entry;
- for(var i = 0; i < list.length; i++) {
- entry = list[i];
- var divElement = document.createElement('div');
- divElement.setAttribute('class', 'name');
- var valueNode = document.createTextNode(entry.gd$email[0].address);
- divElement.appendChild(nameNode);
- divElement.appendChild(valueNode);
- document.getElementById("main").appendChild(divElement);
- }
- }
- // Invoke makeRequest() to fetch data from the service provider endpoint.
- // Depending on the results of makeRequest, decide which version of the UI
- // to ask showOneSection() to display. If user has approved access to his
- // or her data, display data.
- // If the user hasn't approved access yet, response.oauthApprovalUrl contains a
- // URL that includes a Google-supplied request token. This is presented in the
- // gadget as a link that the user clicks to begin the approval process.
- 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);
- }
- // Call fetchData() when gadget loads.
- gadgets.util.registerOnLoadHandler(fetchData);
- </script>
- ]]>
- </Content>
- </Module>
。
コピペしただけ。
hogehoge.xmlとして保存する。
外部からhttp://www.example.com/opensocial/hogehoge.xmlとして見える場所に設置。
2) とりあえずShindigを動かして、該当するガジェット別のdomainを取得
lockedDomain機能を有効にしているので、gadgetXML毎のiframeのdomainが分からない。
SHA1の結果をBase32してみても良いんだけど、Shindig動かした方が楽しかったので、
そうした。
表示された結果のソースファイルを見てみると、、
http://59vs5qn45f2fqulv6shuu20n9v6ig218.gadget.example.com/gadgets/ifr?url=http://www.example.com/opensocial/hogehoge.xml
などとiframeのsrc属性だったので、ホスト名を抜き出す。
すると、
59vs5qn45f2fqulv6shuu20n9v6ig218.gadget.example.com
なんてなものが抜き出せる。
3) google アカウントのManageDomainsページにアクセスし、2)で取得したドメインを登録
2)で抜き出したgadgets毎のiframeのドメインをgoogleアカウントのmanageDomainsから登録する。
URLはhttps://www.google.com/accounts/ManageDomains。
で、「Add a New Domain」ってところから2)で取得した
59vs5qn45f2fqulv6shuu20n9v6ig218.gadget.example.com
を登録。
Googleからverifyなリクエストが飛んでくるので、とある決まったファイルを置いておく。
(登録時にGoogleの画面に従えばOK)
4) 3)で登録するとconsumer keyとconsumer secretが発行されるので、それをconfig/oauth.jsonへ記述。
3)で登録完了すると、
OAuth Consumer Key: 59vs5qn45f2fqulv6shuu20n9v6ig218.gadget.example.com
OAuth Consumer Secret: hogehogehoge
などと表示されるので、それをshindigのconfig/oauth.jsonへ記述する。
記述したoauth.jsonは以下な感じ。
- {
- "http://www.example.com/opensocial/hello.xml" : {
- "google" : {
- "consumer_key" : "59vs5qn45f2fqulv6shuu20n9v6ig218.gadget.example.com",
- "consumer_secret": "hogehogehoge",
- "key_type" : "HMAC_SYMMETRIC"
- }
- }
- }
3行目の"google"は、ガジェットの<Service name="google">と合わせておくっぽい。
5) ガジェットXMLの一部修正
Googleからコピーしてきたガジェットを修正する。
ガジェットXMLの10行目、
- <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" />
というところを
- <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken" />
とoauth_callback以降を削除。
とりあえず、今はコールバックいらないんで。
また、shindig.propertiesのshindig.signing.global-callback-urlも空にセット。
6) shindigコンパイル&起動
そしたら、shindigをコンパイル&起動する。
で、ガジェットを表示してみる。
すると画面に
Personalize this gadget
というリンクが表示されるんで、クリックする。
すると、別Windowが開いて、Googleにログインしていなければ、Googleのログイン画面が表示される。
ログインすると、
The site 59vs5qn45f2fqulv6shuu20n9v6ig218.gadget.example.com is requesting access to your Google Account for the product(s) listed below.
なんて書かれたページが表示される。そのページの「Grant access」ボタンを押下。
ボタンを押下すると、
You have successfully granted 59vs5qn45f2fqulv6shuu20n9v6ig218.gadget.example.com access to your Google Account. You can revoke access at any time under 'My Account'.
なんて書かれたページが表示される。このWindowはもういらないので、閉じる。
するとあら不思議。
ガジェットにメールアドレス一覧が表示されているではありませんか!
そんだけ。
--
まだいろいろ試したわけじゃないので、なんとも言えないが、
ガジェットを表示する際のOWNERとVIEWERをGoogleのアカウント名と合わせておかないと
駄目かも。
--
OWNERを合わせておかないと、ダメかも。
OWNERが違うときにはGoogle側でエラーになる。
--
ちなみに上記は、Shindig-1.1-SNAPSHOTでやった。
(Java版)
--(2009/08/11)
OwnerIdとViewerIdが違うとShindigでエラーになる。
OAuthRequest.javaの320行目あたり参照。
.
0 コメント:
コメントを投稿