2008 年 10 月
簡介
觀眾
本文將逐步說明如何建立 Blogger 小工具。本文假設您已熟悉 Google Data API 和 JavaScript 用戶端程式庫。您也應精通 JavaScript,並有使用 gadgets.* 實作 OpenSocial 小工具的經驗。API。
這個範例也示範如何在小工具中順利使用外部程式庫。我使用 jQuery (主要是為了 UI 效果) 和 TinyMCE,這款所見即所得的富文字編輯器外掛程式非常實用。
動機
只要使用少量的 JavaScript,就能建立透過 Google Data API 搭配 JSON 的小工具。這類小工具的主要缺點是資料公開且為唯讀。如要建構更有趣的小工具,您需要存取使用者的私人資料 (這需要驗證)。到目前為止,還沒有充分運用 Google 帳戶 API 的好方法。AuthSub 需要瀏覽器重新導向,而 ClientLogin 會在用戶端公開使用者的憑證。就連破解type="url"小工具也很不方便。
輸入 OAuth Proxy。
OAuth Proxy
如果您不熟悉 OAuth,這是一種驗證標準,可讓使用者與其他網站或小工具共用私人資料。OAuth 規格規定所有資料要求都必須經過數位簽署。這對安全性來說是好事,但如果是 JavaScript 小工具,管理私密金鑰和建立數位簽章並不安全。此外,跨網域問題也讓情況更加複雜。
幸好,只要善用小工具平台提供的 OAuth Proxy 功能,就能解決這些問題。OAuth Proxy 的設計宗旨是讓小工具開發人員的工作更輕鬆。這項功能會隱藏大部分的 OAuth 驗證詳細資料,並為您處理繁重的工作。Proxy 會代表小工具簽署資料要求,因此您不需要管理私密金鑰,也不必擔心要求簽署問題。輕輕鬆鬆就能上手!
OAuth Proxy 是以名為 Shindig 的開放原始碼專案為基礎,該專案實作了 Gadget 規格。
注意: OAuth Proxy 僅支援使用 gadgets.* API 且在 OpenSocial 容器中執行的 Gadget。舊版小工具 API 不支援這項功能。
開始使用
本教學課程的其餘部分將著重於建立小工具,以存取使用者的 Blogger 資料。我們將逐步說明如何進行驗證 (使用 OAuth Proxy)、使用 JavaScript 用戶端程式庫,以及最後將項目發布至 Blogger。
驗證
首先,我們需要告知小工具使用 OAuth。如要這麼做,請在小工具的 <ModulePrefs> 區段中新增 <OAuth> 元素:
<ModulePrefs> ... <OAuth> <Service name="go>ogle&<quot; Access url="https://www.google.com/accounts/OAuthGetAccessToken&>quot; <method="GET" / Request url="https://www.google.com/accounts/OAuthGetRequestToken?scope=http://www>.blogg<er.com/feeds/" method="GET" / Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken? oauth_call>back<=http://>o<auth.g>modul<es.com/gadge>ts/oauthcallback" / /Service /OAuth ... /ModulePrefs
<Service> 元素中的三個網址端點對應至 Google 的 OAuth 權杖端點。查詢參數說明如下:
scope要求網址中必須有此參數。小工具只能存取這個參數中使用的
scope(s) 資料。在本範例中,小工具將存取 Blogger。如果小工具要存取多個 Google Data API,請將額外的scope(s) 與%20串連。舉例來說,如要同時存取日曆和 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),我們會將使用者導向該網址登入。小工具會顯示「登入 Blogger」,並將 href 設為oauthApprovalUrl的值。 - 接著,使用者點按「登入 Blogger」,OAuth 核准頁面就會在另一個視窗中開啟。小工具會顯示「我已核准存取權」連結,等待使用者完成核准程序。
- 在彈出式視窗中,使用者會選擇授予/拒絕存取小工具的權限。點選「授予存取權」後,系統會將使用者導向
http://oauth.gmodules.com/gadgets/oauthcallback,並關閉視窗。 - 小工具會辨識視窗是否已關閉,並重新要求使用者資料,嘗試第二次存取 Blogger。如要偵測視窗關閉,我使用了彈出式視窗處理常式。如果未使用這類代碼,使用者可以手動點選「我已核准存取權」。
- 小工具現在會顯示一般 UI。除非在「IssuedAuthSubTokens」IssuedAuthSubTokens中撤銷驗證權杖,否則這個檢視畫面會持續存在。
因此從上述步驟來看,小工具的概念有三種不同狀態:
- 未經驗證。使用者必須啟動核准程序。
- 等待使用者核准存取資料。
- 已通過驗證。小工具會顯示正常運作狀態。
在我的小工具中,我使用 <div> 容器分隔每個階段:
<Content type=">h<tml" <![CDATA[ !-- Normal state of the gadget. The user is authen>ticated <-- div id="main" >sty<le="display:none" form id="postForm" name="postF>orm&qu<ot; onsubmit="savePost(this); retu><rn f>alse;&<quot; div id=&quo>t;messages" st<yle="display: none"/div div class="selectF><eed&qu>ot;Publish to: < selec><t id=&q>uot;po<stFe>edUri&<quot; name="post>FeedU<ri&>quot; <disabled="disabled"optionloading> blog <li>st.../o<pti>on/sel<ect /div h4 style="clear:both"Title/h4 input>< type=&qu>ot;tex<t" id="title>" name="title&<quo><t;/ h4Content/h4 textarea id=&qu>ot;con<tent" name="content" style="widt>h:100%<;><height:200px;"/textarea h4 style="fl>oat:lef<t;"Labels (comma separated)/h4img src="blogger.png&quo>t<; style="flo>at:rig<ht&quo><t;>/ < i>n<put >ty<pe="text" id="categories>&qu<ot; name="categories&q>uot;/ pinput <ty>p<e=&q>uo<t;submit" id="submitButton&q>uot<; value="Save"/ > input type="<;c>h<eckbo<x" id="draft" name="draft" checked>=<"checked"/ label for="><draf>t&q<uot;Draft?/label/p /form /div div id="approval&q>uot; s<tyle="displ>ay:< n>one" < a> hr<e><f="#" id="><pe>r<sona>lize>&q<uot;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" h3Loading.../h3 pimg src="ajax-loader.gif"/p /div ]] /Content>
每個 <div> 都會使用 showOnly() 單獨顯示。如要瞭解該函式,請參閱完整範例小工具。
使用 JavaScript 用戶端程式庫
如要在 OpenSocial 中擷取遠端內容,請使用 gadgets.* API 呼叫 gadgets.io.makeRequest 方法。不過,由於我們要建構 Google Data 小工具,因此不需要使用 gadgets.io.* API。請改用 JavaScript 用戶端程式庫,其中有專用方法可向各項 Google Data 服務發出要求。
注意:撰寫本文時,JavaScript 程式庫僅支援 Blogger、Google 日曆、
Google 聯絡人、
Google 財經和 Google Base。如要使用其他 API,請在不使用程式庫的情況下使用 gadgets.io.makeRequest。
載入程式庫
如要載入 JavaScript 程式庫,請在 <Content> 區段中加入一般載入器,並在小工具初始化後匯入程式庫。將回呼饋送至 gadgets.util.registerOnLoadHandler() 有助於判斷小工具何時準備就緒:
<Content type=">h<tml" ![CDATA<[ ... script src="https://www.go><ogle.co>m/j<sapi"/script script ty>pe="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'); fet<chData(>); })>; < } 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(entryR<oot) { 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 帳戶 API 討論論壇。
資源
- 撰寫 OAuth 小工具 (完整的小工具說明文件)
- 搭配 Google Data API 使用 OAuth (說明如何搭配 Google Data API 使用 OAuth 的文章)
- 網頁應用程式的 OAuth 驗證 (完整 OAuth 說明文件)
- JavaScript 用戶端程式庫
- Google Accounts API 討論區
.png?hl=zh-tw)