Blog at trepca.si My thoughts, serialized

Authorizing makeRequest calls from OpenSocial containers

OpenSocial is a solid standard, but when it comes to documentation it can get pretty confusing, especially because every container has their own quirks and documentation. Anyway, I needed to communicate with my own server and as it appears OpenSocial provides a method makeRequest just for that.

It sends a request to container server, which then makes a request to your server and same way back. So in short, container acts as a proxy between your application and server. For this to be secure, it uses OAuth signing protocol. Both hosts share a secret key which they use to sign and verify requests.
Issuing and signing a request on the client is pretty easy:
 
function makeSignedRequest() {
  var params = {'person': 1, 'context':100};
  params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
  params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
  params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
  var url = "http://www.test.com/resource";
  gadgets.io.makeRequest(url,authResponse, params);
}
function authResponse(data) {
  for(var i in data) {
    alert(i+'='+data[i]);
  }
}

Verifying a request on the server (python code, you’ll also need OAuth package):

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
 
from oauth import oauth
 
signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()
OAUTH_CONSUMER_KEY = 'http://www.myspace.com/xxxxxxxx'
OAUTH_SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
 
def _get_request_signature(url, params):
    '''Returns a signature built with consumer key, secret and parameters of the request'''
    request = oauth.OAuthRequest(http_url=url, parameters=params)
    consumer = oauth.OAuthConsumer(OAUTH_CONSUMER_KEY, OAUTH_SECRET_KEY)
    return signature_method.build_signature(request, consumer, None)
 
def request_secure(url, params):
    '''Tests if request for given URL(and parameters) is safe'''
    try:
        remote_signature = params['oauth_signature']
        local_signature = _get_request_signature(url, params)
        return local_signature == remote_signature
    except KeyError:
        return False
    except:
        logging.exception("error verifying signature: %r"%params)
        return False
 
if __name__ == '__main__':
    # build signature
    test_signature = _get_request_signature("http://www.test.com/resource", dict(person=1,
                                                                                 context=100))
    assert request_secure("http://www.test.com/resource", dict(person=1,
                                                               context=100,
                                                               oauth_signature=test_signature))
    print "All ok."
That’s it. Looks easy, right? I wish documentation was more clear on this, I spent half a day figuring this out.
Started blogging, again