Friday, March 16, 2012

A Working Facebook OAuth Logout URL

Last week I worked on the Facebook integration of a web app of ours. The starting point was the Facebook Connect button. We need to authenticate Facebook users with our app (single sign-on), get and manage their data, and logout them from both our app and Facebook (single sign-off). All that by using the new OAuth 2.0 protocol and Java Servlets.

Not a difficult task for the first part of the process, that is, single sign-on. Problems emerged when working on the logout part. According to Facebook terms and conditions for apps, all external web apps must implement the single sign-off (SSO) method to logout Facebook users. Reasons for that are quite obvious: if you logout from an external web app without SSO the Facebook session remains active with all the security risks arising from it.

Unfortunately, official documentation on logout is poor or focused on SDKs. I found loads of forum and blog posts on how to accomplish the single sign-off. It took me about a week to check almost all proposed solutions. Crap. All crap. Found algorithms, cowboys and aliens, but none worked for me (and for the most part of the Facebook app developers as I saw on comments).

After a very long search, I found a post from a guy whose Javascript SDK-based solution worked for me. However, since our web app is going to be cross-device, I wondered about doing Facebook authentication by means of Java and Servlets for compatibility reasons with our web app, since Javascript can be disabled on the desktop browser and isn't always available on the mobile one.

Finally, I found and tested the right URL for logging out Facebook users:

https://www.facebook.com/logout.php?next=[YourAppURL]&access_token=[ValidAccessToken]

You must have a valid Facebook access_token and the next parameter must be your app URL (field URL of your web site in the tab Web Site of the Facebook App configuration). More parameters can be added, but those are the most important to get the work done.

Just a few words on the access_token. It’s in the form of:

XXXXXX|YYYYYYYYYYYY|ZZZZZZ

You must take it as a whole. Not only the Y part as I read on some posts. And that parameter is NOT the session_key.

Remember to encode URL before to pass it as the parameter next, too. In Java it's:

URLEncoder.encode([yourAppURL], “UTF-8”)

Have fun!