Lesson 10: Interact with your own Backend

From VZ Developer Wiki
Jump to: navigation, search

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:

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:


  • Lesson 10: Interact with your own Backend