Skip to content

Web Two-Point-Oh-No!

July 15, 2010

First off, I whole heartily apologize for the lame blog post title.  Not only is it a bad pun, it’s misleading given the topic of this post, which is to chronicle my efforts integrating KitchenPC in with Facebook Connect, Facebook’s single-signon approach.  It seems if you want to be a real Web 2.0 website, not only do you need to use the right fonts, but you also need the “Log in with Facebook” button.  This realization was the catalyst of yesterday’s headaches.

The second reason, and arguably more important, for this post is to feebly attempt to organize the chaos of information out on the web that one must grudgingly wade through to untangle the mess that are the Facebook APIs.  I’m hoping this post will help out someone like me, who until yesterday didn’t know the first thing about integrating in with Facebook or providing a single sign-in mechanism.  To make matters worse, since I’m using the .NET Framework (which is all but unsupported by Facebook), there exists only the most brief and usually contradictory information across blogs, various CodePlex projects, and other web based bulletin boards.

Most people who begin investigating Facebook integration with a .NET based backend will stumble across this site almost immediately.  This is Facebook’s attempt to provide links to various APIs developed for Facebook.  There’s a few out there (mostly unstable, alpha code that hasn’t been changed in a year or more), but it seems that the main one is the Facebook Developer Toolkit library that is supported by Microsoft, though written by a third party contracting firm called Clarity Consulting.  Unfortunately, they don’t have the clarity required to write a coherent API or document anything they’ve done.  Most APIs in their documentation are left completely blank or just place holders for examples that may never come.  Maybe they should use a Wiki, which might encourage others to update it.

The sample is fairly easy to setup, which assumes you’ve created a Facebook application, and takes only minor tinkering to get working.  One thing I noticed is that people like to confuse the terms API Key and Application ID.  Often, they are merged into one super-ambiguous term such as “Application Key”.  The API Key is an alphanumeric (actually hex value) string, and the Application ID is a numeric value (apparently a 64-bit number).  The example refers to this key, mostly using the incorrect terms, so you have to guess which one they mean.  I’ll just go over the “Connect” sample, which is available in the Samples.zip file here.

Once you open the solution file in Visual Studio, the two files of importance are Default.aspx (which contains some script to edit), and Default.aspx.cs (which contains everything else.)  In Default.aspx, at the bottom of the page you’ll find the following line of Javascript:

FB.init(“9a6e2f9bf3b0be5b695e95d8a6f71f34”, “xd_receiver.htm”);

This initializes the Facebook framework, and also does stuff like transform that funky <fb:login-button> tag into an actual button.  The first parameter will be your API key (the hex one) of your Facebook application.  If you accidentally type in your Application ID (numeric), the logon still works but the session will not be valid and Facebook Developer Toolkit is not nice enough to report any useful error to you.  IsConnected() just returns false and explains no reason why.  This was about ten minutes of hair pulling for me.

Next, edit the Default.aspx.cs file.  Under the Private Members region, there’s two constants (no, not death and taxes) – APPLICATION_KEY (there’s that damn made up name again!) and SECRET_KEY.  Your APPLICATION_KEY is your API Key, which is the same value you have in your script file.  The SECRET_KEY is obviously the Application Secret, which you don’t even tell your best friend.  Once you set this up, stuff should work.  Oh wait, no it won’t.

One thing you’ll have to keep in mind if you’re developing locally is your URLs for redirects might not match.  If your local development machine is running on localhost, and your application’s “Connect URL” is something else, you’ll see an error when clicking on the Login button.  There’s two theories on how to fix this.

  • Fake out your dev machine by editing the HOSTS file to point yourdomain.com to 127.0.0.1.  Since all the redirection is through client-side script and Facebook itself doesn’t actually hit your server, this should work fine.  For me it’s a bit hacky and requires developers to mess around with junk.
  • Create two Facebook applications.  One points to http://localhost/ as the Connect URL and one points to your production site.

I went with the latter route.  I have a “KitchenPC” application which points to kitchenpc.com, and a “KitchenPC Development” application, which is hidden, that points to http://localhost.  Also, I use port 80 for my development web server; if you use another port, that will have to be in your Connect URL as well.

Ok, now everything should work.  When you login to Facebook and trust the application, the page will display various information it obtained through your account.  This is a great start!  However, if you actually want to do anything useful, this is where the headaches will begin.

The first thing I wanted to do was retrieve the email address from Facebook so I could check if the user already had an account on KitchenPC, and ask the user if they wished to link to that Facebook account.  There’s also a way to do this with comparing email hash values but I decided to avoid this approach.  Since the email address is not provided by default, you have to ask for this permission explicitly.  The FDT documentation only provided one example on how to prompt the user for permissions, and this involved using a Facebook client side control that pops up a prompt asking for the permission.  However, I wasn’t too thrilled about the idea of having yet another prompt after the user logs on to then ask for more permissions.  I wanted to grant email access when the application is first installed on the user’s account, as I’d seen before on other sites;  something like this:

I knew this was possible, but I had to resort to the Facebook documentation (which assumes you’d use PHP for a task like this) to figure out the deal.  One of the first things I noticed is that all the Facebook SDK samples used different syntax.  For one, FB.Init() took a different signature.  Theirs looked like this:

FB.init({appId: ‘xxxxxxxxx’, status: true, cookie: true, xfbml: false});

Next, their <fb:login-button> had all sorts of neat features, such as a “perms” attribute that would ask for explicit permissions (exactly what I needed!), had the ability to override the text, and other features I might desire.  However, none of these attributes worked for me when I tried.  Upon digging into this more, I noticed they also included a different Javascript file.  Instead of the FeatureLoader.js.php file that the FDT sample was using, they used a file called all.js.  This seemed to be the key.  When I started using the new file, my Facebook Login control now worked and asked for the permissions I wanted, and allowed me to use other featured from Facebook’s documentation.  Now the problem is the FDT no longer worked.  Even with valid session cookies, ConnectSession.IsConnected() returned false.  After a little debugging, I noticed the cookies that Facebook created after logging in were different if I included the all.js file, versus the working FeatureLoader.js.php.  Upon a bit more research, a few things were revealed.  First, FeatureLoader.js.php is old and deprecated.  Facebook warns against it, insisting the use of their new Javascript API which is designed around OAuth 2.0.  The FDT is designed around the old Javascript API, which is still supported but most likely not for long.  After digging through the Discussions for the FDT looking for help, it appeared I was not alone.  There were literally a dozen or more posts on this subject.  Some posts were aware of the exact problem and were asking for a timeline on when FDT would support the new APIs, some posters were like me and completely clueless to the fact that there were multiple APIs and what the differences were between them.  Very few of the posts had any answers or even replies.

It seems that support for the .NET FDT is waning, and even Facebook isn’t really backing it.  This means there’s no real .NET support for Facebook, and FDT may or may not eventually get around to supporting the new Javascript library.  Unfortunately, the other .NET libraries for Facebook aren’t much better, mostly abandoned or very unstable.  I did run across one that supported OAuth 2.0 but it had some dependancies on some .NET libraries that I didn’t want to mess with.

After more research, I dug across a blog post that really saved the day!  This was a post by a guy named Nathan Totten who, like me, was grumbling about the lack of .NET support for Facebook, but unlike me, was knowledgable enough to do something about it.  He posted this.

This code is able to deserialize the new OAuth 2.0 cookie and build a valid session.  I pretty much copied and pasted the code into my project as is, and was able to hack together a session object under the debugger.  Be sure the read the comments on his blog post, as they’ll reveal a few more steps to get everything working.  Once this was working, the rest was pretty easy.  ConnectSession.IsConnected() will still return false, as it tries to find the old cookie, but you can mock up a Api object by setting the session manually like so:

Api api = new Api(session);
api.Session.SessionKey = sessionKey;
api.Session.UserId = userId;

The sessionKey and userId of course come from the ConnectService class that Nathan built.  When this is done, you can use the Api object normally or use FQL queries to obtain any information you have permission to from Facebook.  Sure, this is a bit of a hack but it’ll do for now until there’s something better.  I chatted with Nathan a bit over email and apparently his company is working on a new, fully featured .NET API for Facebook.  I wish him luck with this project as there really needs to be a single library that is well maintained, documented, and supported by the community.

The goods news is that now I have the ability to sign on to KitchenPC using a Facebook account, and even link a Facebook account with an existing KitchenPC account.  This framework will also pave the way for features such as publishing KitchenPC content to a Facebook user’s news feed, or “Liking” content on the KitchenPC site.  Ah the joys of Web 2.0-ness.

Advertisements

From → Technical

One Comment
  1. Hey, thanks for the mention. You should check out our new api at facebookdevelopertoolkit.codeplex.com. We are going to be posting an update tomorrow that will make .Net development much easier.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: