Lesson 10: Interact with your own Backend
General Guidelines | XML Specification | Features | Views | JavaScript API | REST API | Tutorials | OAuth
Lesson 09: Storing and Retrieving AppData | Back to overview | Lesson 11: Separate viewer and owner |
This tutorial shows how you can call your own backend from a gadget, how you can verify the calls signature and how you can call the opensocial rest API from your backend.
Making a call from your gadget
In your gadget you can use the gadgets.io.makeRequest method to call an external url. For security reasons you should always either use HTTPS or a signed request. For this tutorial we perform a signed request to our backend. You also have to be sure that your backend domain is specified within the ModulePrefs section by an AllowedDomain element. Otherwise the request is blocked because of security reasons.
A small test gadget could look like this:
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Backend Test Gadget">
<Require feature="opensocial-0.8"/>
<Require feature="views" />
<AllowedDomain name="your-backend.net" />
</ModulePrefs>
<Content type="html">
<![CDATA[
<script>
function init() {
var url = 'URL TO YOUR BACKEND';
var params = {};
params[gadgets.io.RequestParameters.AUTHORIZATION]=gadgets.io.AuthorizationType.SIGNED;
gadgets.io.makeRequest(url, requestCallback, params);
}
function requestCallback(obj) {
document.getElementById('dump').innerHTML = obj.data;
}
gadgets.util.registerOnLoadHandler(init);
</script>
<div id='dump'></div>
]]>
</Content>
</Module>
OpenSocial 0.9 introduces a shorter API definition to do the same thing (see Osapi.http_(v0.9)):
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Backend Test Gadget">
<Require feature="opensocial-0.9"/>
<Require feature="views" />
<AllowedDomain name="your-backend.net" />
</ModulePrefs>
<Content type="html">
<![CDATA[
<script>
function init() {
var url = 'URL TO YOUR BACKEND';
osapi.http.get({
'href' : url,
'format' : 'json',
'authz' : 'signed'
}).execute(function(response) {
document.getElementById('dump').innerHTML = obj.data;
});
}
gadgets.util.registerOnLoadHandler(init);
</script>
<div id='dump'></div>
]]>
</Content>
</Module>
Verifying the signature
When you recieve a call from the container at your backend, the first thing you have to do is to validate the signature. For more information on OAuth signature validation see the OAuth spec. We recommend that you use an OAuth library which is available for a multitude of languages to help you with receiving and making OAuth calls.
In this tutorial we use PHP and OAuth 1.0A ready library (see OAuth Libraries) which you can use to validate the signature:
//include OAuth Library
//extend OAuth Library to fetch given public key
class MyOAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod_RSA_SHA1 {
protected function fetch_public_cert(&$request) {
$s = curl_init();
curl_setopt($s,CURLOPT_URL,$_GET['xoauth_signature_publickey']);
curl_setopt($s, CURLOPT_RETURNTRANSFER, 1);
$cert = curl_exec($s);
curl_close($s);
return $cert;
}
protected function fetch_private_cert(&$request) {
return;
}
}
$request = OAuthRequest::from_request();
$server = new MyOAuthSignatureMethod_RSA_SHA1();
$return = $server->check_signature($request, null, null, $_GET['oauth_signature']);
if (! $return) die('invalid signature');
//do your business logic
The tutorial at http://www.christophbuente.de/2009-10-29-opensocial-gadgets-apps-fur-studivz-selbst-entwickeln/ gives you an example on how to do this with a Ruby backend.
Preloading
If you want the Gadget Server to pre-fetch a resource that you want to use later on you have two possibilities.
Either specify the resource in your moduleprefs like this:
<ModulePrefs title="Demo Preloads" description="Demo Preloads">
<Require feature="opensocial-0.9" />
<Preload href="http://www.example.com" />
</ModulePrefs>
If you then perform a makeRequest to this resource for the first time the result will be returned instantly without any HTTP request
gadgets.io.makeRequest("http://www.example.com", response, params);
Data Pipelining
Or you can use Data Pipelining so that you can use the fetched data together with proxied content, OpenSocial Templates or just access it through the JavaScript API. See Data_Pipelining for details.
Proxied Content
Another way to fetch data from your server would be by using Proxied_Content. Here the gadget server sends a request to your server while it renders the gadget and uses the HTML you are returning as the content for the gadget.
Calling the OpenSocial REST API
Of course you can also call our OpenSocial REST API to get further information about users. Authorization is done by a two-legged OAuth process where the consumer_key is your gadget id and the consumer_secret is the secret key you find in the gadget sandbox. In order to be able to make a two-legged and not a three-legged authorization the parameter xoauth_requestor_id is mandatory.
$consumer = new OAuthConsumer($_GET['opensocial_app_id'], 'YOUR GADGETS OAUTH SECRET');
$url = 'http://YOUR CURRENT PLATFORMS OPENSOCIAL REST ENDPOINT/people/@me/@self';
$params = array('xoauth_requestor_id' => $_GET['opensocial_owner_id']);
//you also can add additional query parameters as you like
$params['count'] = '100';
$outreq = OAuthRequest::from_consumer_and_token($consumer, null, 'GET', $url, $params);
$sig = new OAuthSignatureMethod_HMAC_SHA1();
$outreq->sign_request($sig, $consumer, null);
$params = $outreq->get_parameters();
$pairs = array();
foreach ($params as $key => $value) {
$pairs[] = $key . '=' . urlencode($value);
}
$pstring = implode('&', $pairs);
$ch = curl_init($url . '?' . $pstring);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION ,1);
curl_setopt($ch, CURLOPT_HEADER ,0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER ,1);
$data = json_decode(curl_exec($ch), true);
echo "Hello " . $data['entry']['displayName'];
Possible endpoints are:
- http://meinvz.gadgets.apivz.net/social/rest
- http://studivz.gadgets.apivz.net/social/rest
- http://schuelervz.gadgets.apivz.net/social/rest
- http://sandbox.gadgets.apivz.net/social/rest
You can detect the right endpoint for the current call by the oauth_consumer_key parameter.
Further Information
You can find further information and examples in other languages at:
- http://wiki.opensocial.org/index.php?title=Introduction_To_Signed_Requests
- http://wiki.opensocial.org/index.php?title=Validating_Signed_Requests
|