facebook-ios-sdk logout question

Eduardo Coelho picture Eduardo Coelho · Jun 3, 2011 · Viewed 22.5k times · Source

I have seen a lot of questions here regarding the Facebook Graph API but I still haven't find a solution for simple 'login'/'logout' operations using it. Looks like the Single Sign-On style is causing more confusion than benefits.

I'd like to know if it is possible have the following situation:

  1. Enter in the app (no accessToken/expirationDate created).
  2. Perform a login using SSO by calling authorize:delegate: method (application goes background and the login is made in the 'global' scope (Facebook App/Mobile Safari), asking for the user credentials.
  3. Enter back in the app (now logged in, both accessToken and expirationDate are saved to NSUserDefaults).
  4. Perform a logout by calling the logout: method (now logged out, both accessToken and expirationDate are removed from NSUserDefaults)
  5. Attempt to perform a login again, with exactly the same steps done in 2.

I realize that when I call logout:, I do really log out from Facebook (accessToken is invalidated) from my App scope, not from the global scope (Facebook App/Mobile Safari). In 5.) when I try to log in again, the application goes to background and the login attempt is made again in Facebook App/Mobile Safari as usual, however I'm getting a screen saying that I'm already logged in:

You have already authorized .... Press "Okay" to continue. Logged in as ... (Not You?).

It's a strange behavior for the user that has just logged out in my App. My question is:

"Can I really log out from facebook (I mean 'global' scope) from inside my App? This would affect other apps using the facebook credentials too. However, if I can't to do this, how can I avoid the 'strange behavior' describe above?

Thanks

Answer

gadildafissh picture gadildafissh · Dec 1, 2011

Eduardo,

I feel your pain! I spent the better part of a day working on this issue. I have discovered that when you use SSO and the call:

Called from your code:

[facebook logout:self];

Facebook API method:

- (void)logout:(id<FBSessionDelegate>)delegate {

  self.sessionDelegate = delegate;
  [_accessToken release];
  _accessToken = nil;
  [_expirationDate release];
  _expirationDate = nil;

  NSHTTPCookieStorage* cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage];
  NSArray* facebookCookies = [cookies cookiesForURL:[NSURL URLWithString:@"http://login.facebook.com"]];

  for (NSHTTPCookie* cookie in facebookCookies) {
    [cookies deleteCookie:cookie];
  }

  if ([self.sessionDelegate respondsToSelector:@selector(fbDidLogout)]) {
    [_sessionDelegate fbDidLogout];
  }
}

The facebook API does invalidate the access token and expirationdate variables and attempts to delete the mobile Safari cookies, but for some reason, probably Apple's fault the cookies are not really deleted. So when you attempt to login in the next time your mobile Safari will see the cookie and it says:

"You have already authorized .... Press "Okay" to continue. Logged in as ... (Not You?)."

Until either Facebook finds a fix or Apple fixes their broken API we must bypass SSO through Safari. Below are the changes I made to Facebook.m in order to force the old login dialog. If you used these changes they may not work forever but it is my guess that they will work for a very long time. Also to be sure this worked with the most recent facebook API I updated to the latest as of this post (Nov 2011 build).

Called from your code:

[facebook authorize:permissions];

Facebook API method:

- (void)authorize:(NSArray *)permissions {
  self.permissions = permissions;

//  [self authorizeWithFBAppAuth:YES safariAuth:YES];
    [self authorizeWithFBAppAuth:NO safariAuth:NO];
}

If this helps you please up rate this thread and my post to help others find it.

gadildafissh