Why Won't FB.Connect.logoutAndRedirect work?

I was banging my head against a Facebook Connect problem with one of my clients' Rails apps recently, and I thought I'd share a useful tidbit I gleaned from the experience, in case it can spare someone else the headache I had.

This app originally supported just plain-old users who created an account at the site with a username and password. Then the client requested that I add Facebook Connect as an authentication option. Using the facebooker gem, most of the work was straightforward. If a user chooses the Facebook Connect option when signing up or logging in, a User record is created and a FacebookUser record is associated with that User. The real problem came with trying to log out a Facebook Connect user.

As far as I can tell from the Facebook documentation, if you provide a logout at your site, and someone is logged in via Facebook Connect, you should call the Facebook API to log that user out of Facebook, too. This is done by using either the FB.Connect.logoutAndRedirect or the FB.Connect.logout function in the javascript API. I wanted to send my users to the /logout URL in the application to do some additional cleanup of the User record, and to use facebooker to clear out the Facebook cookies, so the logoutAndRedirect method seemed to be the way to go. Unfortunately, for reasons that I couldn't immediately figure out, it would work in Safari or Chrome, but not in Firefox.

So, I tried using the logout javascript method as an alternative. It accepts a callback function as an argument (and here's the key) that gets executed immediately if the Facebook user has no current Facebook session. Even though the logoutAndRedirect method did absolutely nothing (and returned no error) in Firefox, the logout method would call that callback (even though it didn't log me out of Facebook). This was progress -- though I couldn't log out of Facebook in Firefox with this function, at least I could log out of my app by redirecting to /logout in the callback, and I wouldn't be immediately logged back in after a page load or two in Safari (which was the problem I was experiencing with just depending on the facebooker methods rather than using the javascript).

The trick that finally sealed the deal and got all browsers working similarly had nothing to do with the app, though... it was a browser setting. Safari had 3rd-party cookies enabled, and Firefox didn't. Having that setting turned off prevented the logoutAndRedirect method from working as it should, thus preventing the redirect to the /logout URL. Having that setting turned on caused the Facebook cookies to almost immediately come back, when using just the server-side code to do the logout.

To get everybody logged out, then, regardless of cookie settings, the way to do it is to the use FB.connect.logout with a callback function that redirects to /logout. This successfully logs the user out of Facebook if he has third-party cookies enabled, and logs the user out of your app by destroying the current session even if he doesn't.

Comments