2008 年 10 月
簡介
目標對象
這篇文章將逐步引導您建立 Blogger 小工具。本文假設您已熟悉 Google Data API 和 JavaScript 用戶端程式庫。另外,您也應該透過 JavaScript 精通,並使用小工具*來實作 OpenSocial 小工具。API。
此範例也說明如何在小工具中成功使用外部程式庫。我使用過 jQuery (主要是對 UI 效果的影響) 和 TinyMCE (一款功能強大的 WYSIWYG RTF 格式編輯器外掛程式)。
動機
只要建立 JavaScript 版本,就能以 JSON 和任一 Google Data API 建立小工具。這類小工具的主要好處在於
這是公開的資料,以及唯讀資料。若要建構更有趣的小工具,您必須存取使用者的私人資料 (需要驗證的項目)。截至目前為止,Google 帳戶 API 並沒有完全改善的功能。AuthSub 需要瀏覽器重新導向,而 ClientLogin 會公開用戶端的憑證。即使駭客入侵 type="url"
小工具也很容易。
輸入 OAuth Proxy。
OAuth Proxy
如果您不熟悉 OAuth,這種驗證方式可讓使用者與其他網站或小工具分享自己的私人資料。OAuth 規格要求所有資料要求都經過數位簽署。這在安全性方面十分重要,但在 JavaScript 小工具中,管理私密金鑰及建立數位簽章並不安全。 此外,解決了跨網域問題的問題。
幸好,現在透過小工具 OAuth 的一項功能來解決這些問題。OAuth Proxy 可讓小工具開發人員使用起來更得心應手。可隱藏大部分 OAuth 的驗證詳細資料,為您代勞。 Proxy 會代表您的小工具簽署資料要求,因此您不必管理私密金鑰或擔心簽署要求。這項功能很有用!
OAuth Proxy 是以名為 Shindig 的開放原始碼專案為基礎,這是實作小工具規格的實作專案。
注意:只有採用 gadgets.*
API 且在 OpenSocial 容器中執行的小工具才支援 OAuth Proxy。舊版小工具 API 不支援這項功能。
開始使用
本教學課程的其他部分將著重於建立小工具,以存取使用者的 Blogger 資料。我們會先使用 OAuth Proxy 進行驗證,並使用 JavaScript 用戶端程式庫 最後將文章張貼到 Blogger。
驗證
首先,您必須告知小工具使用 OAuth。如要這麼做,請在小工具的 <ModulePrefs>
區段中加入 <OAuth>
元素:
<ModulePrefs> ... <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.blogger.com/feeds/" method="GET" /> <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken? oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" /> </Service> </OAuth> ... </ModulePrefs>
<Service>
元素中的三個網址端點對應到 Google 的 OAuth 憑證端點。以下是查詢參數的說明:
scope
「要求網址」是必要參數。您的小工具只能存取這個參數中使用的
scope
資料。在這個範例中,小工具將存取 Blogger。如果您的小工具想要存取多個 Google Data API,請將額外的scope
與%20
串連。舉例來說,如要同時存取 Google 日曆和 Blogger,請將範圍設為http://www.blogger.com/feeds/%20http://www.google.com/calendar/feeds/
。oauth_callback
此為「授權網址」中的選用參數。使用者核准資料存取權後,OAuth 核准頁面將重新導向至這個網址。 您可以選擇放棄這項參數、將參數設為自己的「已核准網頁」,或是偏好使用「
http://oauth.gmodules.com/gadgets/oauthcallback
」。日後,當使用者首次安裝您的小工具時,即可提供最佳使用者體驗。這個網頁會提供一段會自動關閉彈出式視窗的 JavaScript 程式碼。
現在,我們的小工具已經使用 OAuth,因此使用者必須核准他們存取資料。驗證流程如下:
- 此小工具一次載入,並嘗試存取使用者的 Blogger 資料。
- 使用者尚未授予小工具的存取權限,因此要求失敗。幸好,回應中傳回的物件含有網址 (
response.oauthApprovalUrl
),我們會將使用者用來登入。小工具會顯示「Sign in to Blogger」(登入 Blogger),並將其 href 的值設為oauthApprovalUrl
。 - 接下來,點選 [登入 Blogger], OAuth 核准頁面隨即會在另一個視窗中開啟。小工具會顯示使用者「已完成核准程序」連結,等待使用者完成核准程序。
- 在彈出式視窗中,使用者可以選擇授予或拒絕我們小工具的存取權。按一下 [授予存取權] 之後,系統就會
前往「
http://oauth.gmodules.com/gadgets/oauthcallback
」 視窗就會關閉。 - 小工具會辨識該視窗並再次要求存取使用者的資料,藉此再次存取 Blogger。為了偵測視窗的關閉情形,我使用彈出式視窗處理常式。如果您不使用這類驗證碼,使用者可以手動按下 [我已獲得存取權]。
- 小工具現在會顯示一般使用者介面。除非 IssuedAuthSubTokens 下撤銷驗證權杖,否則這個檢視畫面會持續保留。
從上述步驟開始,小工具有三種不同狀態的概念:
- 未驗證。使用者必須開始進行核准程序。
- 正在等待使用者核准他們的資料存取權。
- 已驗證。小工具會顯示正常功能狀態。
我的小工具使用了 <div>
容器來分隔各個階段:
<Content type="html"> <![CDATA[ <!-- Normal state of the gadget. The user is authenticated --> <div id="main" style="display:none"> <form id="postForm" name="postForm" onsubmit="savePost(this); return false;"> <div id="messages" style="display: none"></div> <div class="selectFeed">Publish to: <select id="postFeedUri" name="postFeedUri" disabled="disabled"><option>loading blog list...</option></select> </div> <h4 style="clear:both">Title</h4> <input type="text" id="title" name="title"/> <h4>Content</h4> <textarea id="content" name="content" style="width:100%;height:200px;"></textarea> <h4 style="float:left;">Labels (comma separated)</h4><img src="blogger.png" style="float:right"/> <input type="text" id="categories" name="categories"/> <p><input type="submit" id="submitButton" value="Save"/> <input type="checkbox" id="draft" name="draft" checked="checked"/> <label for="draft">Draft?</label></p> </form> </div> <div id="approval" style="display: none"> <a href="#" id="personalize">Sign in to Blogger</a> </div> <div id="waiting" style="display: none"> <a href="#" id="approvalLink">I've approved access</a> </di <!-- An errors section is not necessary but great to have --> <div id="errors" style="display: none"></div> <!-- Also not necessary, but great for informing users --> <div id="loading"> <h3>Loading...</h3> <p><img src="ajax-loader.gif"></p> </div> ]]> </Content>
每個 <div>
都會使用 showOnly()
自行顯示。如要進一步瞭解該函式,請參閱完整小工具小工具。
使用 JavaScript 用戶端程式庫
如要在 OpenSocial 中擷取遠端內容,您可以使用 gadgets.*
API 呼叫 gadgets.io.makeRequest
方法。
不過,由於我們建構的是 Google 資料小工具,所以不需要輕觸 gadgets.io.*
API。建議您改用 JavaScript 用戶端程式庫,這個程式庫有特殊的方法可向各個 Google Data 服務發出要求。
注意:撰寫本文時,JavaScript 程式庫僅支援 Blogger、日曆、聯絡人、財經和 Google Base。如要使用其他 API,請在沒有程式庫的情況下使用 gadgets.io.makeRequest
。
載入程式庫
如要載入 JavaScript 程式庫,請在 <Content>
區段加入常用載入器,並在小工具初始化後匯入程式庫。向 gadgets.util.registerOnLoadHandler()
傳送回呼有助於判斷小工具何時就緒:
<Content type="html"> <![CDATA[ ... <script src="https://www.google.com/jsapi"></script> <script type="text/javascript"> var blogger = null; // make our service object global for later // Load the JS library and try to fetch data once it's ready function initGadget() { google.load('gdata', '1.x', {packages: ['blogger']}); // Save overhead, only load the Blogger service google.setOnLoadCallback(function () { blogger = new google.gdata.blogger.BloggerService('google-BloggerGadget-v1.0'); blogger.useOAuth('google'); fetchData(); }); } gadgets.util.registerOnLoadHandler(initGadget); </script> ... ]]> </Content>
呼叫 blogger.useOAuth('google')
會指示程式庫使用 OAuth Proxy (而不是一般驗證方法的 AuthSubJS)。
最後,小工具會嘗試透過呼叫 fetchData()
來擷取使用者的 Blogger 資料。該方法定義如下。
正在擷取資料
現在一切都設定完畢,該如何將 GET
或 POST
的資料提供給 Blogger?
OpenSocial 中的常見模式是定義小工具中的 fetchData()
函式。這個方法通常會處理不同階段的驗證,並使用 gadgets.io.makeRequest
擷取資料。由於我們使用的是 JavaScript 用戶端程式庫,因此 gadgets.io.makeRequest
將由呼叫 blogger.getBlogFeed()
取代:
function fetchData() { jQuery('#errors').hide(); var callback = function(response) { if (response.oauthApprovalUrl) { // You can set the sign in link directly: // jQuery('#personalize').get(0).href = response.oauthApprovalUrl // OR use the popup.js handler var popup = shindig.oauth.popup({ destination: response.oauthApprovalUrl, windowOptions: 'height=600,width=800', onOpen: function() { showOnly('waiting'); }, onClose: function() { showOnly('loading'); fetchData(); } }); jQuery('#personalize').get(0).onclick = popup.createOpenerOnClick(); jQuery('#approvalLink').get(0).onclick = popup.createApprovedOnClick(); showOnly('approval'); } else if (response.feed) { showResults(response); showOnly('main'); } else { jQuery('#errors').html('Something went wrong').fadeIn(); showOnly('errors'); } }; blogger.getBlogFeed('http://www.blogger.com/feeds/default/blogs', callback, callback); }
第二次呼叫這個函式時,response.feed
會包含資料。
附註:getBlogFeed()
使用相同的函式來處理其回呼和錯誤處理常式。
將項目張貼到 Blogger
最後一個步驟是將新項目張貼至網誌。以下程式碼示範如何按下 [儲存] 按鈕後會發生什麼事。
function savePost(form) { jQuery('#messages').fadeOut(); jQuery('#submitButton').val('Publishing...').attr('disabled', 'disabled'); // trim whitespace from the input tags var input = form.categories.value; var categories = jQuery.trim(input) != '' ? input.split(',') : []; jQuery.each(categories, function(i, value) { var label = jQuery.trim(value); categories[i] = { scheme: 'http://www.blogger.com/atom/ns#', term: label }; }); // construct the blog post entry var newEntry = new google.gdata.blogger.BlogPostEntry({ title: { type: 'text', text: form.title.value }, content: { type: 'text', text: form.content.value }, categories: categories }); // publish as draft? var isDraft = form.draft.checked; if (isDraft) { newEntry.setControl({draft: {value: google.gdata.Draft.VALUE_YES}}); } // callback for insertEntry() var handleInsert = function(entryRoot) { var entry = entryRoot.entry; var str = isDraft ? '(as draft)' : '<a href="' + entry.getHtmlLink().getHref() + '" target="_blankt">View it</a>'; jQuery('#messages').html('Post published! ' + str).fadeIn(); jQuery('#submitButton').val('Save').removeAttr('disabled'); }; // error handler for insertEntry() var handleError = function(e) { var msg = e.cause ? e.cause.statusText + ': ' : ''; msg += e.message; alert('Error: ' + msg); }; blogger.insertEntry(form.postFeedUri.value, newEntry, handleInsert, handleError); }
結語
現在您已擁有必要的基礎,可以開始撰寫 Google Data API 之上的小工具。
這篇文章旨在說明 OAuth Proxy 如何讓小工具進行驗證的簡易程度。結合這項強大工具與 Google Data JavaScript 用戶端程式庫,即可輕鬆建立有趣的互動式小工具。
如果您對本文有任何疑問或意見,請前往 Google Accounts API 論壇。
資源
- 撰寫 OAuth 小工具 (完整小工具說明文件)
- 將 OAuth 與 Google Data API 搭配使用 (瞭解如何將 OAuth 與 Google Data API 搭配使用)
- 網路應用程式的 OAuth 驗證 (完整 OAuth 文件)
- JavaScript 用戶端程式庫
- Google Accounts API 論壇