- 浏览: 2224981 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
wahahachuang5:
web实时推送技术使用越来越广泛,但是自己开发又太麻烦了,我觉 ...
细说websocket - php篇 -
wahahachuang8:
挺好的,学习了
细说websocket - php篇 -
jacking124:
学习了!支持你,继续
初窥Linux 之 我最常用的20条命令 -
aliahhqcheng:
应该是可以实现的,没有看过源码。你可以参考下:http://w ...
Jackson 框架,轻易转换JSON
Creating a Google Data Gadget
- ▸Google Data APIs
- ▸Google Data Protocol
- ▸More Resources
- ▾Articles
- ▸JavaScript Samples
Creating a Google Data Gadget
October 2008
Contents
Introduction
Audience
This article will walk you through creating a Blogger gadget. It assumes you are familiar with theGoogle Data APIsand theJavaScript client library. You should also be fluent in JavaScript and have some experience implementing an OpenSocial gadget using thegadgets.* API.
This example also demonstrates how to successfully use external libraries in your gadgets. I've usedjQuery(mainly for its UI effects) andTinyMCE, a great WYSIWYG rich text editor plugin.
Motivation
It takes very little JavaScript to create a gadget that usesJSONwith
one of the Google Data APIs. The major annoyance of such a gadget is that the data is public and read-only. To build more interesting gadgets, you need access to a user's private data (something that requires authentication). Until now, there hasn't been a
great way to take advantage of theGoogle Account APIs.
AuthSub requires browser redirects and ClientLogin exposes a user's credentials, client-side. Even hacking up atype="url"
gadget
has been inconvenient.
Enter the OAuth Proxy.
OAuth Proxy
If you're not familiar with OAuth, its an authentication standard that allows a user to share their private data with another website or gadget. TheOAuth specificationrequires that all data requests are digitally signed. This is great for security, but in the case of a JavaScript gadget, managing private keys and creating digital signatures is insecure. There's also the added complication of cross-domain issues.
Luckily, these problems are solved by taking advantage of a feature from the gadgets platform called the OAuth Proxy. The OAuth Proxy is designed to make life easier for gadget developers. It hides much ofOAuth's authentication detailsand does the heavy lifting for you. The Proxy signs data requests on behalf of your gadget, so there's no need to manage private keys or worry about signing requests. It just works!
The OAuth Proxy is based on an open-source project calledShindig, which is an implementation of the gadget specification.
Note:The OAuth Proxy is only supported for gadgets utililzing thegadgets.*
API
and running in OpenSocial containers. It is not supported for thelegacy
gadgets API.
Getting Started
The rest of this tutorial will focus on creating a gadget to access a user's Blogger data. We'll go through authentication (using the OAuth Proxy), using the JavaScript client library, and finally, posting a entry to Blogger.
Authentication
First things first, we need to tell the gadget to use OAuth. To do that, add the<OAuth>
element
in the gadget's<ModulePrefs>
section:
<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>
The three url endpoints in the<Service>
element correspond toGoogle's
OAuth token endpoints. Here's explanation of the query parameters:
-
scope
This parameter is required in the Request URL. Your gadget will only be able to access data from the
scope
(s) used in this parameter. In this example, the gadget will access Blogger. If your gadget wanted to access more than one Google Data API, concatenate the additionalscope
(s) with a%20
. As an example, if you wanted to access both Calendar and Blogger, set the scope tohttp://www.blogger.com/feeds/%20http://www.google.com/calendar/feeds/
. -
oauth_callback
This parameter is optional in the Authorization URL. The OAuth approval page will redirect to this URL after the user has approved access to their data. You can choose to leave off this parameter, set it to your own "approved page", or preferably, use
http://oauth.gmodules.com/gadgets/oauthcallback
. The later provides the best user experience when users first install your gadget. That page provides a snippet of JavaScript that automatically closes the popup window.
Now that we have our gadget using OAuth, the user needs to approve access to their data. Here's the authentication flow:
- The gadget loads for the first time and attempts to access the user's Blogger data.
-
The request fails because the user hasn't granted access to the gadget. Fortunately, the object returned in the response contains a URL (
response.oauthApprovalUrl
) where we'll send the user to login. The gadget displays the "Sign in to Blogger" and sets its href to the value ofoauthApprovalUrl
. - Next, the user clicks "Sign in to Blogger" and the OAuth approval page opens in a separate window. The gadget waits for the user to finish the approval process by displaying a link: "I've approved access".
-
In the popup, the user will choose to grant/deny access to our gadget. Once they click "Grant access", they're taken to
http://oauth.gmodules.com/gadgets/oauthcallback
and the window closes. - The gadget recognizes the window closed and attempts to accesss Blogger a second time by re-requesting the user's data. To detect the window closing, I've used apopup handler. If you don't use such code, the user can manually click the "I've approved access".
- The gadget now displays its normal UI. This view will persist unless the authentication token is revoked underIssuedAuthSubTokens.
So from the steps above, gadgets have the notion of three different states:
- Unauthenticated. The user needs to start the approval process.
- Waiting for the user to approve access to their data.
- Authenticated. The gadgets displays it's normal functional state.
In my gadget, I've used<div>
containers to separate each stage:
<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>
Each<div>
is displayed by itself usingshowOnly()
.
See thefull example
gadgetfor details on that function.
Using the JavaScript client library
To fetch remote content in OpenSocial, you make a call to thegadgets.io.makeRequest
method
using thegadgets.*
API. However, since we're building a Google Data gadget, there's
no need to touch thegadgets.io.*
APIs. Instead, leverage the JavaScript client library
which has special methods for making requests to each Google Data service.
Note: At the time of writing this article, the JavaScript library only supportsBlogger,Calendar,Contacts,Finance,
andGoogle Base.
To use one of the other APIs, usegadgets.io.makeRequest
without the library.
Loading the library
To load the JavaScript library, include the common loader in the<Content>
section
and import the library once the gadget has been initialized. Feeding a callback togadgets.util.registerOnLoadHandler()
will
help determine when the gadget is ready:
<Content type="html"> <![CDATA[ ... <script src="http://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>
The call toblogger.useOAuth('google')
tells the library to use the OAuth Proxy (instead
ofAuthSubJS- its normal authentication method).
Lastly, the gadget attempts to retrieve the user's Blogger data by callingfetchData()
.
That method is defined below.
Fetching data
Now that things are all setup, how do we actuallyGET
orPOST
data
to Blogger?
A common paradigm in OpenSocial is to define a function calledfetchData()
in your
gadget. This method typically handles the different stages of authentication and fetches data usinggadgets.io.makeRequest
.
Since we're using the JavaScript client library,gadgets.io.makeRequest
gets replaced
by a call toblogger.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); }
The second time this function is called,response.feed
contains data.
Note:getBlogFeed()
uses the same function for it's callback and
error handler.
Post an entry to Blogger
The last step is to post a new entry to a Blog. The code below demostrates what happens when the user clicks "Save" button.
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); }
Conclusion
Now you have the building blocks to start coding a gadget on top of the Google Data APIs.
Hopefully this article has given you an appreciation for how simple the OAuth Proxy makes gadget authentication. Combining this power tool with the Google Data JavaScript client library makes it easy to build interesting, interactive, and sophisticated gadgets.
If you have any questions or comments on this article, please visit us in theGoogle Accounts APIs discussion forum.
Resources
- Writing OAuth Gadgets(full gadgets documentation)
- Using OAuth with the Google Data APIs(article on using OAuth with the Google Data APIs)
- OAuth Authentication for Web Applications(full OAuth documentation)
- JavaScript client library
- Google Accounts APIs discussion forum
相关推荐
【标题】"Google gadget 代码" 涉及到的是使用编程技术创建一个Google小工具,主要用于阅读RSS Feed。Google小工具(Gadgets)是Google的一项服务,允许开发者创建可嵌入到iGoogle个性化首页或其他支持Google ...
Jira的Gadget使用介绍 Jira的Gadget是一种插件式的小工具,可以帮助用户更方便地管理和跟踪项目问题。下面将介绍Jira的Gadget的使用方法和各种类型的Gadget。 一、添加Gadget的基本步骤 1. 登陆Jira系统,进入...
Linux UVC Gadget数据结构是针对USB视频类设备(Universal Video Class, UVC)在Linux内核中的实现,主要用于在USB设备端模拟一个UVC摄像头。这个数据结构涉及到USB传输、视频缓冲管理和V4L2(Video for Linux ...
### RK3399 HID Gadget 配置为键盘详解 #### 一、RK3399 USB Gadget 概述 RK3399 是一款高性能的嵌入式处理器,支持多种USB设备模式,包括USB Host和USB Device。通过内核中的USB gadget功能,RK3399 可以模拟成...
标题中的“Weather_download1.gadget.rar_gadget”表明这是一个与天气相关的Windows小工具,它被压缩在RAR文件中。小工具(Gadget)是Windows操作系统中的一种桌面增强应用,通常用于提供实时信息或便捷功能,比如...
在Linux系统中,"Linux Gadget Keyboard添加"指的是将Linux设备用作USB外设键盘(Gadget Keyboard)的过程。这通常涉及到对内核驱动的修改和应用层测试程序的开发,以便让Linux设备能够模拟一个USB键盘并发送按键...
### Linux USB Gadget 驱动详解 #### 一、概述与应用场景 **Linux USB Gadget** 驱动是一种特殊的驱动程序,用于使运行Linux的设备能够作为USB从设备工作。这种驱动允许Linux设备模拟各种USB设备角色,如U盘、键盘...
在Linux操作系统中,USB Gadget驱动框架是一种特殊的技术,它允许Linux系统作为USB设备被其他主机识别和使用。这一框架使得Linux系统能够模拟各种类型的USB设备,如键盘、鼠标、网络适配器甚至存储设备。在本文中,...
RNDIS(Remote Network Driver Interface Specification)和ETHERNET GADGET驱动是嵌入式系统和移动设备中常用的技术,主要用于将设备模拟成一个网络设备,从而可以通过USB接口提供网络连接功能。在IBM服务器环境中...
标题 "gadgetserial 驱动 win7可用" 指出这是一款适用于Windows 7操作系统的gadgetserial驱动程序。gadgetserial驱动是用于将USB设备模拟为串行(COM)端口的一种技术,常见于USB转串口适配器或者某些特殊的USB设备...
首先,SelectorGadget是一款针对Google Chrome浏览器的扩展程序,它的主要功能是帮助用户快速获取网页元素的CSS选择器。安装完成后,只需在浏览器中打开目标网页,点击该插件图标,然后在网页上选择感兴趣的元素,...
例如,通过Google Maps API显示地图信息,或使用Twitter API发布推文。 在安全方面,虽然Gadget是小型工具,但仍然需要防止XSS(跨站脚本攻击)和CSRF(跨站请求伪造)等网络安全威胁。开发者应确保输入验证、数据...
青竹导航:QDaohang1.00beta.gadget 青竹斗地主:Qdoudizhu1.0.gadget 青竹MM斗地主:QdoudizhuMM1.0.gadget 青竹开心翻牌:QFanpaiGame1.0.gadget 青竹超级计算器:QjisuanQi1.0.gadget 青竹连连看:QllKanGame1.0.gadget...
the gadget driver for linux os Linux_USB_gadget设备驱动.pdf USB设备驱动开发深度解析-宋宝华.pdf 嵌入式Linux下USBGadget驱动框架研究.pdf
这款插件适用于谷歌浏览器(Chrome),它的工作原理是在用户界面上选定一个元素后,SelectorGadget会立即提供对应元素的CSS选择器。选择器是用于在CSS中标识HTML元素的字符串,通过这个字符串,我们可以精确地在样式...
在Linux系统中,RNDIS Ethernet Gadget驱动是用于将Linux设备模拟为USB以太网设备,使得Linux设备能够通过USB连接到另一台计算机或设备,并作为网络连接的提供者。这种技术特别适用于嵌入式系统,如树莓派或其他小型...
在Linux操作系统中,USB Gadget功能配置是一种将Linux设备模拟为USB外围设备(Gadget)的技术,让Linux系统能够作为USB主机(Host)的设备端。这种技术在嵌入式系统、物联网设备以及各种需要与USB主机通信的场景中...
### Gadget API 参考手册知识点详解 #### 一、引言 《Gadget API 参考手册》是由 David Brownell 编写的一份详细文档,主要针对的是那些希望在嵌入式 Linux 系统中开发 USB 设备端驱动程序的开发者。这份手册提供...
USB Video Class (UVC) Gadget驱动是针对USB设备端点设计的一种软件组件,它使得嵌入式系统或计算机能够模拟一个USB视频设备,从而在主机系统上作为摄像头或者其他视频输入设备来使用。这个"uvc.rar"压缩包包含的...
USB Ethernet/RNDIS Gadget Drivers是用于将USB设备模拟为网络设备(以太网适配器)的技术。这项技术基于Remote Network Driver Interface Specification (RNDIS),它允许USB设备通过USB接口提供网络功能,比如让...