I want to use GFC to authenticate users for my site.
It sounds like it should be doable, right? I think it is, but at the moment it's kind of hard. In fact it's so hard (or I'm so soft) that I haven't been able to do it (yet). Let recap a bit what it is GFC (Google Friend Connect) does;
1. If you enable GFC for your site, you can add GFC widgets which let people comment and rate the page you add the widgets to and interact in various ways. You can also add any custom OpenSocial widget you like (AFAIK)
2. One of the widgets you must have is the login widget which let anybody 'join' your site. When they do so, Google open up a separate window which let them choose their method of authentication; Google, Yahoo, OpenId, et.c., with various suboptions in Google's case).
3. Now Google keeps track of unique users that act on the widgets on your site, let them unjoin, log in and out, and so on.
4. The original identity provider (Google, Yahoo, et.c.) is still used as always for changing password, user info, et.c.
This is really great. The immediate thought when realizing how things work is that you want somehow to leverage this great new functionality that Google provide: To have a secure, authenticated site where you don't need to manage anyones identity, password changes, et.c.
So, I started trying to do so.
The first easy thing was to create a custom OpenSocial widget on my own site, that I pull in using the custom widget option on the 'social gadgets selection' on the GFC admin site; http://www.google.com/friendconnect .
What happens is that you let GFC generate a HTML snippet that loads an open social script from google, which in turn pulls in your script - through - google's proxy server. In any event, the script resides on a directory on your server, and get to land on you page (which was just recently in another directory) and can then suddenly utilize all GFC magic - check the id and name of current viewer, his/hers friend list, et.c. Neat.
But.
If you just post this info back to your server using standard Ajax - and trust the info you get - you're lost. How can you be sure that it really was your script that send that info? No, you need to make Google's GFC server send certified info back to your server about the current viewer.
Luckily enough, there's an OpenSocial call called (..) makeRequest, which makes an ajax call through the Container (Googl'es GFC servers, in this case, since Google/GFC is the Container. The Container would normally be LinkedIn, MySpace, Orkut, et.c.) to any given destination. For example your server, which actually hosts the page where the GFC widgets are hopping about.
http://code.google.com/apis/opensocial/docs/0.8/reference/gadgets/#gadgets.io.makeRequest
Is a great place to learn what can be done with this. For one thing, you can send back some good info. My simple OpenSocial script did just this, and made sure to begin in a nice and easy manner, not forcing any encryption, using AuthorizationType.NONE, like this;
...
...
var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.NONE;
params[gadgets.io.RequestParameters.REFRESH_INTERVAL] = 5;
var url = "http://xxxxxxxxxxxxx";
console.log("calling url... '"+url+"'");
gadgets.io.makeRequest(url, reqcb, params);
};
function reqcb(data)
{
console.log("reqcb called....");
console.dir(data);
}
...
...
And this works well. Looking more carefully into the link above, one reads the following:
If opt_params[gadgets.io.RequestParameters.AUTHORIZATION]
is set to gadgets.io.AuthorizationType.SIGNED
, the container needs to vouch for the user's identity to the destination server. The container does this by doing the following:
Removing any request parameters with names that begin with
oauth
,xoauth
, oropensocial
(case insensitive).Adding the following parameters to the request query string:
- opensocial_viewer_id
- Optional.
The ID of the current viewer, which matches thegetId()
value on the viewer person object. - opensocial_owner_id
- Required.
The ID of the current owner, which matches thegetId()
value on the owner person object. - opensocial_app_url
- Required.
The URL of the application making the request. Containers may alias multiple application URLs to a single canonical application URL in the case where an application changes URLs. - opensocial_instance_id
- Optional.
An opaque identifier used to distinguish between multiple instances of the same application in a single container. If a container does not allow multiple instances of the same application to coexist, this parameter may be omitted. The combination ofopensocial_app_url
andopensocial_instance_id
uniquely identify an instance of an application in a container. - opensocial_app_id
- Optional.
An opaque identifier for the application, unique to a particular container. Containers that wish to maintain backwards compatibility with the opensocial-0.7 specification may include this parameter. - xoauth_public_key
- Optional.
An opaque identifier for the public key used to sign the request. This parameter may be omitted by containers that do not use public keys to sign requests, or if the container arranges other means of key distribution with the target of the request.
Signing the resulting request according to section 9 of the OAuth specification.
So, if I could use a SIGNED request instead, the GFC proxy servers would add all the info I need and crave for my service, especially a guaranteed identity of the current page viewer. Using this unique id in my tables gives me to power to associate this identity with anything I'd like on my site. Ok. Fine.
What happens when I use SIGNED? Well, the callback function always gets back the verbose, detailed and informative error message "404: Not found", in a JSON object, but still..
Now you might think that I don't know the first thing about public cryptography, signing requests and tossing certificates about in the rich and useful variety of almost-compatible formats the joyful and friendly cooperation between related companies in the beginning of this century gave rise to, but you'd be wrong.
I can't call myself an expert (any longer), but I have quite a good working knowledge of the above. the problem here is that the documentation makes references to the public certificate of the container, which the receiving service need to verify.
great, but the Container is GFC. Where's their certificate? Maybe this is obvious, I don't know. It isn't for me, anyway. Reading another page which digs deep in the OAuth spec, I find a links I've never seen before, which let me register sites with google and deploy their public certificates;
http://code.google.com/intl/sv-SE/apis/gdata/articles/oauth.html
Has some links that lead to the registration page for web-based applications;
https://www.google.com/accounts/ManageDomains
So I do just that, and use the OAuth playground;
http://googlecodesamples.com/oauth_playground/
to verify that things (seem to work).
Now, I'm not sure that my site, not being an OpenSocial container (surely!) need to register a certificate with Google, but just in case this was needed to make the SIGNED request work, I did so and played around with it.
No luck. The result stays the same; "404: not found". Great.
What I (and possibly **ALL** other site owners starting to use GFC) need, is some information. Anything of the below will be fine, if not else to give some info back to the community instead of the usual Google no-walling;
1. Here's a simple example which demonstrates how to write a simple OS gadget which post back the current viewers unique id and info.
2. Rick caught the flu last week and haven't had the time to write the example. We'll get on it in a couple of weeks.
3. We'll never give that information, stupid Englishmen! Go and boil your bottoms, sons of a silly person!
4. It's impossible to do what you want. Go back to bed.
5. Wow, that's an interesting idea. We hadn't thought of that! We'll get back to you..
Having emptied my reservoir of frustrated incompetence, I must end with stating the fact that despite all the trouble I've had in trying to get the site authentication to work, I've at least got my money's worth :)
[UPDATE]
Kevin Marks commented on one of my posts on the open social mailing list that GFC does not support signed requests at the moment. We got a number 4!! Yay! Thanks for the info, and let's hope that this gets added real soon.
Cheers,
PS