Sunday, February 28, 2010

Super-simple authentication using Google Friend Connect

I've been following Google friend Connect since it came out, since it's a very interesting API.

For me, what's interesting about it has always been that it takes care of the authentication for a site owner. This is not the basic use-case, mind you. The basic use cases seems to be the simple addition of site-separate, rich, social widgets.

This is by no mean bad, but the first thing I wanted to do with GFC was to just put up the first, simple 'join this site' widget, and then use the magic to let anyone who had a Google. Yahoo, AIM, OpenID, et.c. account just log in to my site, using a unique user id  provided by Google.

This proved quite hard in the beginning, especially since you basically had to learn a lot of OpenSocial APIs just to do something non-trivial. Since a couple of months back, the GFC APIs has become richer and also simpler.  The meaning of this blog post is to show you in a simple way how to leverage GFC for your own authentication, without breaking a sweat.

What you need to do is the following;


  1. Register your site with GFC
  2. Copy-paste in the HTML/Script code for the member gadget into your index.html page (This is done by selecting that gadget and choose to let the GFC page render the code including your site id in a copy-paste box. not terribly hard either).
  3. Do nothing in particular, since the cookie will be send as part of each request to your server (even Ajax ones).
  4. In your server, receive the cookie (looking like this: 'fcauth19038466278488110'), and call GFC from the server, suing the cookie, to get some info about the user.


Using the following code, I make sure that the opensocial API is loaded and that I get a callback when it feels ready. It's not really necessary, but might be of use if you need to access viewer or owner info in your page before or without talking to the server.


   google.load('friendconnect', '0.8');



google.friendconnect.container.loadOpenSocialApi(
{ 
      site: 'xxxxxxxxxxxxxxxxxxxx',
      onload: function() 
     { 
    var fcauth = dojo.cookie("fcauthxxxxxxxxxxxxxxxxxxxx");
    console.log("gfc onload fcauth cookie was '"+fcauth+"'");
    if(fcauth && fcauth != "undefined")
    {                    
        try
        {                  
            dojo.publish("ab_cookie", [fcauth]);          
        }
        catch(e)
        {
            console.log("ERROR in opensocial access.."+e);
        }
    }
}
});



Naturally, you can use an Ajax call inside the callback function directly. I've put all of my logic inside a custom Dojo widget, and if you're not using Dojo, you can do whatever you want.

On the server, which I've coded using node.js and fab, my handler function look like this;

Game.prototype.getUserInfo = function(fcauth, id, cb)
{
    // http://www.google.com/friendconnect/api/people/@owner/@self?fcauth=<your fcauth>
    log.info("getUserInfo called with fcauth='"+fcauth+"' and id='"+id+"'");
    if(!fcauth || fcauth == "undefined")
    {
        log.debug("Skipping null/unathorized request");    
    }
    else
    {
    
    var google = http.createClient(80, "www.google.com");
    var request = google.request("GET", "/friendconnect/api/people/@me/@self?fcauth="+fcauth, {"host": "www.google.com"});
    request.finish(function (response) 
    {        
        response.setBodyEncoding("utf8");
        response.addListener("body", function (chunk) 
        {
            sys.puts("BODY: " + chunk);
            var echunk = eval("("+chunk+")");
            if(cb) cb(echunk);
        });
    })
    }
}


You might choose Python or PHP on the server-side, but I hope that the code is fairly simple to understand. I have the specific code that extract the variables somewhere else, but the function is called with a couple of parameters, where one is 'cfauth'. This is the contents of the cookie set by GFC in the page before.
What the function does is call the GFC server with the cookie, using a special URL which gives back user information about the person just signed in using the cookie. We get back stuff that look like this;

{"entry":{"isViewer":true,"id":"16646299100122442145","thumbnailUrl":"http://www.google.com/friendconnect/profile/picture/9aOJATlcddBMuphbZq6wdLLqvyJr39BwuR60j67nPGv6LO8O_V3xho7gIoeH2juRoEm7jAOdl6_4RK4QAv5aFqD0zzg3TUxVAAZehjEoaEVTjeML9zwRyDFklaql_MxAznquk-Yhm63-ihZtryfA_T3tAwhWv4Szl12A1tZ3xfAa1jAdrE3it5Tx-fAbBW_qPZ3EE4DfALqLKmWC9hqXoXy9wI3rqzoS67CkgsTcU3CJM70ua9Z6OkIpFx7zi3dIXfIFawbodmOhKQ5A7_LeGA","photos":[{"value":"http://www.google.com/friendconnect/profile/picture/9aOJATlcddBMuphbZq6wdLLqvyJr39BwuR60j67nPGv6LNGCV3xho7gIoeH2juRoEm7jAOdl6_4RK11H5aFqDmikrg3TUxVAAZehjEoaEVTjeML9zwRyDFklaql_MxAznquk-Yhm63-ihZtryfA_T3tAwhWv4Szl12A1tZ3xfAa1jAdrE3it5Tx-fAbBW_qPZ3EE4DfALqLKmWC9hqcx0XswI3rqzoS67CkgsTcU3CJM70ua9Z6OkIpFuyzi3dIXfIFawbodmOhKQ5A7_LeGA","type":"thumbnail"}],"displayName":"psvensson"}}

I hope this helps someone, and apologies for not giving out all of my code, which is in a bit of flux.

7 comments:

MDFAAA said...
This comment has been removed by the author.
MDFAAA said...

I have tried to use the gadget for membership under the google friends connect to do what you did here. I am trying to have a login to the website. Everytime I try to add the gadget to my googel sites it just delete some of the codes and would not work. Can you explain how to add this gadget to google sites?

Thanks

Peter Svensson said...

@MDFAAA: I'm not sure I understand what you did exactly, and what happened. However, if you follow the steps listed on the Google friend connect site you should be able to add the membership gadget. It's not very hard.

I just wrote a new article on the latest changes to GFC, and how to read the user id from the cookie: http://unclescript.blogspot.com/2010/02/super-simple-authentication-using.html

HTH

PS

rtfgvb7810 said...

IS VERY GOOD..............................

V@!$#@L! said...
This comment has been removed by the author.
V@!$#@L! said...

its a very good article
but as i got the code to access used id. But i just copy and paste the code in to my javascript but it doesn't give me any output. I am new to programming as I dont know how to use this code ...
Please reply soon...

By using user id i have to use that id for my site's database to store into it.....

Please its urgent...

Dipo Dwijaya said...

I've got an error when I load the script. I use FF10 and Google Chrome, both give me the same results. Dwijayas.