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!

7 comments:

  1. Definitely the best way. The FB javascript SK is not reliable enough. Between IE, Firefox and Chrome, one of them will usually not work.

    The server side redirect as specified here is really fast (I barely see it happen) and so far 100% reliable.

    ReplyDelete
  2. UTF8Encoding utf8 = new UTF8Encoding();
    string unicodeString = "http://test.pathshalamashup.com";
    byte[] encodedBytes = utf8.GetBytes(unicodeString);

    Response.Redirect("https://www.facebook.com/logout.php?next="+encodedBytes+"&access_token="+SocialAuthUser.GetCurrentUser().GetAccessToken(SocialAuthUser.CurrentProvider));


    I did for ASP.NET but it is not working

    ReplyDelete
  3. Hi,

    the Facebook logout link is still valid, then I suppose something in your code is wrong. I don't know ASP.NET and SocialAuth APIs. In Java you can get the work done as follows:

    String accessToken = (String) session.getAttribute("com.mysite.fbtoken");
    String logoutURL = "https://www.facebook.com/logout.php?next=" + URLEncoder.encode("http://www.mysite.com/home.jsp", "UTF-8") + "&access_token=" + accessToken;
    response.sendRedirect(logoutURL);

    Moreover, your code should return anyway an error message when running. It should give you some tip on what is going wrong, i guess.

    In your shoes, I would check if I get really Facebook by the CurrentProvider, and then if a valid token is returned by the method GetAccessToken.

    Hope that help.

    ReplyDelete