Friday, May 18, 2012

Facebook Oauth Logout


I have an application that integrates with Facebook using Oauth 2.



I can authorize with FB and query their REST and Graph APIs perfectly well, but when I authorize an active browser session is created with FB. I can then log-out of my application just fine, but the session with FB persists, so if anyone else uses the browser they will see the previous users FB account (unless the previous user manually logs out of FB also).



The steps I take to authorize are:



  1. Call [LINK: graph.facebook.com/oauth/authorize?client_id...]



This step opens a Facebook login/connect window if the user's browser doesn't already have an active FB session. Once they log-in to facebook they redirect to my site with a code I can exchange for an oauth token.



  1. Call [LINK: graph.facebook.com/oauth/access_token?client_id..] with the code from (1)



Now I have an Oauth Token, and the user's browser is logged into my site, and into FB.



  1. I call a bunch of APIs to do stuff: i.e. [LINK: graph.facebook.com/me?access_token=..]



Lets say my user wants to log out of my site. The FB terms and conditions demand that I perform Single Sign Off, so when the user logs out of my site, they also are logged out of Facebook. There are arguments that this is a bit daft, but I'm happy to comply if there is any way of actually achieving that.



I have seen suggestions that:



A. I use the Javascript API to logout: FB.Connect.logout(). Well I tried using that, but it didn't work, and I'm not sure exactly how it could, as I don't use the Javascript API in any way on my site. The session isn't maintained or created by the Javascript API so I'm not sure how it's supposed to expire it either.



B. Use [LINK: facebook.com/logout.php]. This was suggested by an admin in the Facebook forums some time ago. The example given related to the old way of getting FB sessions (non-oauth) so I don't think I can apply it in my case.



C. Use the old REST api expireSession or revokeAuthorization. I tried both of these and while they do expire the Oauth token they don't invalidate the session that the browser is currently using so it has no effect, the user is not logged out of Facebook.



I'm really at a bit of a loose end, the Facebook documentation is patchy, ambiguous and pretty poor. The support on the forums is non-existant, at the moment I can't even log in to the facebook forum, and aside from that, their own FB Connect integration doesn't even work on the forum itself. Doesn't inspire much confidence.



Ta for any help you can offer. Derek



ps. Had to change HTTPS to LINK, not enough karma to post links which is probably fair enough.


Source: Tips4all

10 comments:

  1. I am having the same problem. I also login using oauth (I am using RubyOnRails), but logout, I do with Javascript using a link like this:

    <a href="/logout" onclick="FB.logout();">Logout</a>


    this first calls the onclick function and performs a logout on facebook, and then the normal /logout function of my site is called.

    Though I would prefer a serverside solution as well, but at least it does what I want, it logs me out on both sites.

    I am also quite new to the Facebook integration stuff and played around the first time with it, but my general feeling is that the documentation is pretty spread all over the place with lots of outdated stuff.
    anyway, maybe that helps you.

    Ciao
    Christoph

    ReplyDelete
  2. This solution no longer works with FaceBook's current API (seems it was unintended to begin with)

    "http://m.facebook.com/logout.php?confirm=1&next=http://yoursitename.com";
    try to give this link on you signout link or button where "yoursitename.com"
    is where u want to redirect back after signout may be ur home page.

    It works..

    ReplyDelete
  3. Here is a full blown walk-through of how to authenticate via the oAuth protocol and log out via a Redirect/Facebook Javascript SDK.

    For your particular problem:

    There are two ways you can log out:


    Log out via Javascript SDK
    Log out via a Redirect to Facebook


    Logging Out with the Javascript Facebook SDK


    Since this is Javascript based, an html page that immediately executes the following:



    This is what the view code will look like (it's very....hackish...unfortunately...but each piece of html is needed....maybe one day Facebook will stream line this...):



    <body>
    <p>Logging you out of Facebook....</p>

    <!-- reference to google's jquery ui library -->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

    <!-- this div element is required...I have no idea why...but when i remove it, the log out doesn't occur -->
    <div id="fb-root">
    </div>

    <!-- pull down Facebook's Javascript SDK -->
    <script src="http://connect.facebook.net/en_US/all.js"></script>

    <!-- execute the following script immediately when the page loads -->
    <script>
    // initialize the library with your Facebook API key
    FB.init({ apiKey: 'yourapikey' });

    // fetch the status so that we can log out

    // you must have the login status before you can logout
    // and if you authenticated via oAuth (server side), this is necessary.
    // if you logged in via the JavaScript SDK, you can simply call FB.logout()
    // once the login status is fetched, call handleSessionResponse
    FB.getLoginStatus(handleSessionResponse);

    // handle a session response from any of the auth related calls
    function handleSessionResponse(response) {
    // if we dont have a session (which means the user has been logged out, redirect the user)
    if (!response.session) {
    window.location = "http://www.example.com/Login/";
    return;
    }

    //if we do have a non-null response.session, call FB.logout(),
    //the JS method will log the user out
    //of Facebook and remove any authorization cookies
    FB.logout(handleSessionResponse);
    }
    </script>
    </body>


    Logging Out of Facebook Using a Redirect


    Alternately (if you dont like the Javascript approach). You can log out of Facebook by redirecting to their logout.php page. Please keep in mind that this approach isn't documented. I used Fiddler2 to see how the Javascript SDK did it's log out magic....so just keep in mind that Facebook can change this anytime without prior notice.



    To log out, just redirect to logout.php with your Api Key and the Original Session Key when you authenticated via the oAuth protocol...the session code/key...not the Graph API Access Token:



    "http://www.facebook.com/logout.php?api_key={0}&;session_key={1}";

    ReplyDelete
  4. You can do this with the access_token:

    $access_array = split("\|", $access_token);

    $session_key = $access_array[1];

    You can use that $session key in the PHP SDK to generate a functional logout URL.

    $logoutUrl = $facebook->getLogoutUrl(array('next' => $logoutUrl, 'session_key' => $session_key));

    This ends the browser's facebook session.

    ReplyDelete
  5. This works as of now - and is documented on facebook's site @ http://developers.facebook.com/docs/authentication/. Not sure how recently it was added to the documentation, pretty sure it wasn't there when I checked Feb-2012


    You can programmatically log the user our of Facebook by redirecting
    the user to

    https://www.facebook.com/logout.php?next=YOUR_REDIRECT_URL&access_token=USER_ACCESS_TOKEN

    ReplyDelete
  6. For Python developers that want to log user out straight from the backend

    At the moment I'm writing this, the trick with m.facebook.com no longer works (at least for me) and user is redirected to the mobile FB login page which obviously is not good for UX.

    Fortunately, FB PHP SDK has a semi-documented solution (in case the link doesn't lead to getLogoutUrl() function, just search look for it on that page). This is also mentioned in at least one other on StackOverflow: Facebook php SDK getLogoutUrl() problem.

    BTW I've just noticed that Zach Greenberg got it right in this question, but I'm adding my answer as a summary for Python developers.

    ReplyDelete
  7. A note for Christoph's answer:
    Facebook Oauth Logout
    The logout function requires a callback function to be specified and will fail without
    it, at least on Firefox. Chrome works without the callback.

    FB.logout(function(response) {});

    ReplyDelete
  8. I can confirm this works:

    https://www.facebook.com/logout.php?
    next=YOUR_REDIRECT_URL
    &access_token=USER_ACCESS_TOKEN


    Source: http://developers.facebook.com/docs/authentication/

    ReplyDelete
  9. For me, setting the domain while constructing the facebook object solved the issue of logout along with $facebook->setSession(null);

    ReplyDelete
  10. it's simple just type : $facebook->setSession(null); for logout

    ReplyDelete