12

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

Eduardo Coelho
  • 1,953
  • 8
  • 34
  • 60

7 Answers7

13

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

gadildafissh
  • 2,243
  • 1
  • 21
  • 26
3

In new SDK of Facebook, you can set login button loginBehaviour property

Below code in swift ...

let fbButton = FBSDKLoginButton()
fbButton.loginBehavior = .Web
dev_m
  • 796
  • 6
  • 12
3

I'm afraid the answer is no, you can't do this.

Your application is in a sandbox, and can't write outside, where global cookies are (for mobile safari) and Facebook app settings (in Facebook app preferences/cookies I think)

You can only warn your user to logout outside of your app...

...Or you can just not use facebook api SSO, but in app login webform, like I do for other reasons.

If you choose that option this pull request might save you some time ;)

Vincent Guerci
  • 14,379
  • 4
  • 50
  • 56
  • I understand the sandbox concept, but If the user doesn't have the Facebook App installed, should I warn "Hey user, go to Safari and clear all cookies"? Looks like through this API I can log in and affect the global scope, but the reverse is not true. Am I wrong? – Eduardo Coelho Jun 03 '11 at 12:53
  • 2
    you are right, it is a SSO, but a multiple sign-out... and principal sign-in is outside of your app, where you do not have any control... People are not supposed to log out frequently, that's why it is fine in most case. If not, I have just edited my answer to bypass SSO in facebook api. – Vincent Guerci Jun 03 '11 at 13:01
  • Things are clearer for me now. However, a regular user doesn't care about this whole global/sandbox story. When faced by a "log out" button it is supposed to log out and in the next time perform a new login (asking for credentials), otherwise the user would think that the log out operation was not successful (although it was successful in the App scope). This is what people are used to do everyday. Given this situation, does a 'log out' button from inside the App makes sense? I could ignore all this and use the old API. What are the guidelines? – Eduardo Coelho Jun 03 '11 at 13:18
  • 1
    use the latest API, but without SSO, using the patch I linked in my answer... (go to SO answer I linked in that gihub pull request comments for more details) You will log-in&out inside your app only. No more problem, and up-to-date api, which is preferable. – Vincent Guerci Jun 03 '11 at 13:46
  • No, you can do it, please look at my answer below – smoothumut Jun 29 '16 at 08:59
3

Hii ,

its not possible , the reason is for Single Sign On (SSO) is not to make user login everytime, he logouts , instead if the user logs in anyone of FB enabled apps - it will use that to login again - This is because the device is mostly used by single person in this case only one user can login in Facebook.

you can't control any app outside of your app - for Example - if u login with Gmail & when you open google.com you can see your username there is currently logged In which has SSO,

Karthikeyan
  • 1,790
  • 12
  • 19
  • Karthieyan, you are correct about the reason for SSO and your example is very clear. My goal was to only control FB usage from within my app and allow multiple users to login and post to their own FB profile. In other words my app is a one device with many users situation. My main question would be: "Is the facebook logout function call supose to require the user to re authenticate with a password, not just a browser cookie, the next time the access Facebook from an app." Thanks in advance, gadildafissh – gadildafissh Dec 01 '11 at 20:19
2

Answer already done, but I just want to clarify it. May be it saved somebody's time.

Go to Facebook.m and change line

  [self authorizeWithFBAppAuth:YES safariAuth:YES];

to

  [self authorizeWithFBAppAuth:YES safariAuth:NO];

It will cause login window appear inside the app. Logout will work perfect. In other words, it will work as it used to in older versions of OS.

Mike Keskinov
  • 11,614
  • 6
  • 59
  • 87
1

in addition to kishnan94 answer. the objective c version is ;

if you want a modal to open up and ask for facebook credentials seperately from Safari or Facebook app, just use the latest facebook sdk and set the login behaviour

FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login setLoginBehavior:FBSDKLoginBehaviorWeb];

this will make the logout process more convenient and less confusing for users without using safari or facebook app accounts.

Muhammad Nabeel Arif
  • 19,140
  • 8
  • 51
  • 70
smoothumut
  • 3,423
  • 1
  • 25
  • 35
0

It seems that this is a bug of Facebook SDK. In a case of the Facebook app is installed on device, access_token is renewed. In other hand, access_token and expirationDate could not be changed. :((

giapnh
  • 2,950
  • 24
  • 20