This is a continuation of #1022932: Local user can't log out when offline_access permission is set.

Loze writes in #96 of that thread

I think I may have figured it out.

in fb_connect.js, on line 20 a click handler is added to all instances of an href with "/logout" in it.
It seems, at least with FF, that the page refreshes before the FB.logout() has a chance to respond.

commenting out line 20
jQuery("a[href^='" + Drupal.settings.basePath + "logout']", context).click(FB_Connect.logoutHandler);

seems to be working for me. This will by pass logging them out with javascript, and let the /logout page handle everything. just as if the user had visited /logout directly.

I'm not sure if this breaks other things, but its now allowing me to logout using FF.

Update:
Alternatively, you can not comment out line 20, and instead add a "return false" to FB_Connect.logoutHandler, right below the line FB_JS.deleteCookie('fbs_' + Drupal.settings.fb.apikey, '/', ''); // apikey

Not sure which method is better.

I'm not sure what's at the root of this issue, but am planning to return false; from FB_Connect.logout(), because that seems like good practice for the click handler.

Comments

Dave Cohen’s picture

Loze also writes:

Yes I have fb_user enabled.
offline_access enabled or not makes no difference for me.
This is only in FF 4.0.1 (possibly older FF versions too)

I don't logically understand it either. :)

also according to FB the FB.logout function returns a response. Possibly waiting for that response before continuing on may help? Im not sure.
http://developers.facebook.com/docs/reference/javascript/FB.logout/

FB.logout does not return anything. It calls a callback, asynchronously. We can't wait for that. (it may never come, http is not so reliable a protocol)

loze’s picture

Some more on this:
I ended up having to put

if(FB.getSession() != null){
			return false;
		}

instead of just return false;
Otherwise clicking the logout link as a user that was registered normally, would return false also, and not go to the /logout page.

Dave Cohen’s picture

I was skeptical of this bug, but I am able to reproduce by following exactly the instruction posted by antosigi. So thanks antosigi for that.

I believe what happens is a race condition. It appears that FB.logout() will not do its job unless the page waits for it. Meanwhile, when the page does NOT wait and instead sends the user to /logout, drupal detects that the user is already logged out. Which sounds desirable, except that going to /logout results in Access Denied and so no logout hooks are run, including fb_user_user(), which would normally complete the logout.

So on the next page the javascript says, "this user is connected to facebook" and it looks to the user like they haven't logged out at all.

Dave Cohen’s picture

Assigned: Dave Cohen » Unassigned
Status: Active » Needs review
StatusFileSize
new759 bytes

My theory in #3 is wrong. It's not that access is denied on /logout. Rather, on the very next page the javascript considers the user still logged into facebook, because they actually are still logged into facebook.

I think the approach loze suggests in #2 will solve the problem. Patch attached.

james.williams’s picture

StatusFileSize
new820 bytes

That works fine for me. We're using it on a site which is going for client testing + approval soon, so I'll let you know of any issues found with it!

One thing I did need to add is that it doesn't redirect properly after logging out. Drupal normally redirects to the homepage, so for now the attached patch does this. Note that it doesn't do anything with a destination currently, which it probably ought to, but that's a secondary problem.

Dave Cohen’s picture

Status: Needs review » Needs work

I think any change to window.location needs to be in the callback function above. Otherwise, you might interrupt the logout handling that facebook needs to do, recreating the original problem.

james.williams’s picture

Do you mean so it looks like this?:

// click handler
FB_Connect.logoutHandler = function(event) {
  if (typeof(FB) != 'undefined') {
    FB.logout(function () {
      // Logged out of facebook.  Need we act on this?
      window.location = Drupal.settings.basePath;     // <--- ADDED LINE
    });
    // Facebook's invalid cookies persist if third-party cookies disabled.
    // Let's try to clean up the mess.
    FB_JS.deleteCookie('fbs_' + FB._apiKey, '/', ''); // app id
    FB_JS.deleteCookie('fbs_' + Drupal.settings.fb.apikey, '/', ''); // apikey
  }
  if (FB.getSession()) {
    // Facebook needs more time to log us out. (http://drupal.org/node/1164048)
    return false;
  }
};

...because unfortunately that doesn't work :-/

I think see what you mean, that facebook won't yet have logged you out - but in using the patch from comment #5 above, I don't get that problem - Could facebook continue logging me out while window.location changes? If so, it wouldn't necessarily be a problem.

Dave Cohen’s picture

That's what I mean. When you say it's not working, you mean it is never reached?

I would change that line to either

window.top.location = Drupal.settings.basePath;

or

FB_JS.reload(Drupal.settings.basePath);

To better work with canvas pages. Although I'm not certain that Drupal.settings.basePath will be correct for canvas pages.

The patch in #5 sends the user to a new page possibly before the logout finishes. It looks like it creates exactly the same problem that this thread is about. So I'm skeptical about it.

james.williams’s picture

Status: Needs work » Needs review

I mean the line is never reached.
But, sorry, you're right that the patch in #5 can send the user to a new page before logout finishes.
So I guess that means the main original issue of not being able to logout is fixed by your patch in #4. However, can we find a solution that also ensures the redirection on logging out (either to the front page, or to any destination in the querystring) does eventually happen?

james.williams’s picture

Status: Needs review » Needs work

Ah, I didn't mean to change the status.

Dave Cohen’s picture

Status: Needs work » Needs review
StatusFileSize
new389 bytes

Try this.

hanoii’s picture

subscribe

spesso’s picture

Drupal for Facebook v. 6.x-3.0-rc13
Firefox 4.0.1 on OSX

"return false" didn't work for me while commenting out line 20 solved my problem.

subscribe.

Dave Cohen’s picture

james.williams (or anyone else), have you tested patch #11?

kevinquillen’s picture

#7 + #11 fixed the issue for me in Safari and FF on Mac.

kevinquillen’s picture

Chrome, Mac, as well.

Dave Cohen’s picture

Status: Needs review » Fixed

Checking in.

james.williams’s picture

Sorry I hadn't replied sooner - bit late not, but yes, it works in FF & Chrome on Ubuntu too. I haven't heard any problems from our client either. Thanks very much Dave :-)

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

rinux’s picture

Hi,

I had this problem myself on a new site. I am using the latest dev, but i didn't work for me. To get around this problem I added at top of fb_connect.js:

$(document).ready(function() {
$('.logout-button').click(function() {
FB.logout(function(response) {
// user is now logged out
});

alert("Du vil nu blive logget ud");
window.location = Drupal.settings.basePath;
});
});

Yes, yes - I know - it is embarissing that I had to add such a function, but now it works at least. Normally I wouldn't add such a code to save myself the embarrassment, but I hope some others will find this as a quick fix.

I will work on a better solution and hope to have it done by the end of this month.

Rino André Johnsen
rino@nymedia.no
Ny Media AS - www.nymedia.no

SolomonGifford’s picture

Has this change made it to drupal 7? I'm having this issue on a d7 site.

cscoleman’s picture

Instead of commenting out line 20 as per the beginning of the thread, what worked for me was to add a leading slash to the logout path:

jQuery("a[href^='" + Drupal.settings.basePath + "/user/logout']", context).click(FB_Connect.logoutHandler);

So "/user/logout']"...etc, instead of "user/logout']", ie.

immafio’s picture

Issue summary: View changes

I don't know if this is still relevant, but I was having this logout problem in firefox for the home page in Drupal 7.

I fixed it by installing the automated Logout module and setting a fast logout time (60 seconds)

For some reason this fixed the problem - I can now logout using the button or waiting for the automation.

-mafio