11

TL;DR Facebook javascript SDK cannot determine the accurate login status of a user who has directly logged out from facebook.com underneath it.

I'm developing a Facebook app using the javascript SDK for authentication. I've noticed that, when the user logs out of Facebook directly (on facebook.com), then the SDK cannot make sense of the user's login state on the app page. I've boiled it down the the following simple test case.

Log in to facebook.com in one tab. In another tab, render the app page below (replacing MY_APP_ID as appropriate). If you are logged into facebook as a user that has never given permissions to this app, click "Login" and grant them. Either way, you should see some events fire indicating you are logged in.

Now, back on the facebook.com tab, log out of facebook. Go to the app tab and click all the buttons (except "Login") and look at the browser console output.

  • When FB.logout is called, nothing happens. The callback is never called. In Chrome, the following error is given: "Unsafe JavaScript attempt to access frame with URL http://my_app.com from frame with URL http://www.facebook.com/. Domains, protocols and ports must match."

  • When FB.getLoginStatus is called, the response says "connected" and has an authResponse object. This is not helpful, though, because it's now incorrect. If, instead, true is passed in for the "force" parameter, then nothing happens (the callback is never called).

  • When FB.getAuthResponse is called, nothing happens (the callback is never called).

  • None of the relevant events are fired during any of this (after logging out of facebook that is).

The issue then is that there seems to be no possible way to legitimately determine the user's login status from the SDK in such a case. Or I'm doing something stupid, though I've boiled it down to the bare minimum.

My end goal here is that I want to be able to do something in this case if the user clicks my logout button after already logging out of facebook. But the SDK gives no viable means of achieving this.

Any ideas or thoughts? Has anyone else experienced this and found a workaround? Thanks!

Simple app page:

<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml' xmlns:fb='http://www.facebook.com/2008/fbml'>
<head>
</head>
<body>
<script>
  window.fbAsyncInit = function() {
    function subFBEvent(name) {
      FB.Event.subscribe(name, function(r) {
        console.log(name);
        console.log(r);
      });
    }
    subFBEvent('auth.login');
    subFBEvent('auth.logout');
    subFBEvent('auth.authResponseChange');
    subFBEvent('auth.statusChange');
    FB.init({
      appId  : 'MY_APP_ID',
      status : true, // check login status
      cookie : true, // enable cookies to allow the server to access the session
      xfbml  : true,  // parse XFBML
      oauth  : true       // use OAuth 2.0
    });
  };
  (function() {
    var s = document.createElement('div'); 
    s.setAttribute('id','fb-root'); 
    document.documentElement.getElementsByTagName("body")[0].appendChild(s);
    var e = document.createElement('script');
    e.src = 'http://connect.facebook.net/en_US/all.js';
    e.async = true;
    s.appendChild(e);
  }());
</script>
<button onclick="FB.logout(function(r) { console.log('FB.logout'); console.log(r); });">Logout</button>
<button onclick="FB.getLoginStatus(function(r) { console.log('FB.getLoginStatus'); console.log(r); });">LoginStatus</button>
<button onclick="FB.getAuthResponse(function(r) { console.log('FB.getAuthResponse'); console.log(r); });">AuthResponse</button>
<fb:login-button>Login</fb:login-button>
</body>
Steve A
  • 251
  • 2
  • 7
  • Just forcing a roundtrip to Facebook servers. Look at http://stackoverflow.com/questions/9482876/how-to-detect-user-logging-out-of-facebook-after-logging-into-my-app/16227872#16227872 – Delmo Apr 26 '13 at 02:42

2 Answers2

0

I don't think this solution will help you now, but i am posting it so that others will not have such a hard time. This is because you are not implementing the FB.getLoginStatus method properly. all you have to do is implement this method

 FB.getLoginStatus(function(response) {
    statusChangeCallback(response);
  });

after the init call. This method will call statusChangeCallback method and do the authentication.

function statusChangeCallback(response) {
    console.log('statusChangeCallback');
    console.log(response);
    // The response object is returned with a status field that lets the
    // app know the current login status of the person.
    // Full docs on the response object can be found in the documentation
    // for FB.getLoginStatus().
    if (response.status === 'connected') {
      // Logged into your app and Facebook.
      testAPI();
    } else if (response.status === 'not_authorized') {
      // The person is logged into Facebook, but not your app.
      document.getElementById('status').innerHTML = 'Please log ' +
        'into this app.';
    } else {
      // The person is not logged into Facebook, so we're not sure if
      // they are logged into this app or not.
      document.getElementById('status').innerHTML = 'Please log ' +
        'into Facebook.';
    }
  }

for more reference you can refer this page of the official documentation https://developers.facebook.com/docs/facebook-login/login-flow-for-web/v2.0

Aniruddha K.M
  • 7,361
  • 3
  • 43
  • 52
  • This doesn't appear to work. A simple test- login on your page. run FB.getLoginStatus, and note the response. In another tab, log out of facebook, return to your page and re-run the command- as far as the api is concerned, you are still logged in. refresh your page, re-run FB.getLoginStatus- finally the page notices. – mseddon Jul 15 '14 at 17:14
  • yes it does not constantly ping the fb server to know the status but when you do call an fb api it checks and works that way. – Aniruddha K.M Jul 16 '14 at 07:16
  • In fact, by changing your FB.getLoginStatus to have an additional parameter `true`, the status will be queried directly, solving the issue. – mseddon Jul 17 '14 at 08:56
  • please let me know where to add this so that it will be useful to others – Aniruddha K.M Jul 17 '14 at 10:20
  • The way I've done it is inside my 'log in' click handler do `FB.getLoginStatus(function() { ... FB.login(...) ... }, true)`, which seems to force the statusChangedCallback to successfully see the change during the login call. Hope that makes sense. – mseddon Jul 17 '14 at 11:33
-2

First of all: why exactly do you want to do this?

The Facebook Login is basically just a convenience for Facebook users to avoid filling in a sign-up or login form on your Web page. It allows an easy setup of a user session on your own Web site, but as far as I know it does not give you any right to directly log a user out of her session at Facebook (nor any other Facebook Login-enabled sites like Stackoverflow). This also works the other way round: if a user logs out of Facebook that does not mean that he should lose all other sessions established through a Facebook Login.

dokaspar
  • 8,186
  • 14
  • 70
  • 98