Sunday, October 15, 2017

FB.logout: what should it do in term of later calls to FB.getLoginStatus?

Leave a Comment

According to https://developers.facebook.com/docs/reference/javascript/FB.logout/

The method FB.logout() logs the user out of your site

what does this mean in terms of later calls to FB.* functions?

Specifically, I'm observing that even though the response to FB.logout has a status of "unknown", after the logout has completed, calling FB.getLoginStatus returns a status of "connected", when passing true as a second parameter or after a page refresh.

This is unexpected to me... perhaps I'm misunderstanding what "logs the user out of your site" means: what does it mean in terms of the FB.* functions? I'm looking to, as best as possible, reverse the process of FB.login. How can this be done?


Update: I was testing at http://localhost:8080. When on http://fbtest.charemza.name/ I realise logout works as I expect, but logout on localhost:8080 logout does not seem to work, i.e. exhibits the problem above. To be clear, no errors appear in the console at any point. The code of the page is below.

To change the question slightly, why does it do this on localhost:8080, and is there a way to develop logout locally where the behaviour is the same as on the public web?

<!doctype html> <html lang="en"> <head>   <meta charset="utf-8">   <title>Facebook Test</title> </head>  <body>   <script>     window.fbAsyncInit = function() {       FB.init({         appId      : '1524395480985654',         cookie     : true,         xfbml      : false,         status     : false,         version    : 'v2.10'       });        FB.AppEvents.logPageView();        };      (function(d, s, id){        var js, fjs = d.getElementsByTagName(s)[0];        if (d.getElementById(id)) {return;}        js = d.createElement(s); js.id = id;        js.src = "https://connect.facebook.net/en_US/sdk.js";        fjs.parentNode.insertBefore(js, fjs);      }(document, 'script', 'facebook-jssdk'));      document.addEventListener("DOMContentLoaded", function(event) {       document.getElementById("loginButton").addEventListener("click", function() {         FB.login(function(response) {           console.log('FB.login', response);         });        });        document.getElementById("logoutButton").addEventListener("click", function() {         FB.logout(function(response) {           console.log('FB.logout', response);         });       });        document.getElementById("getLoginStatusButton").addEventListener("click", function() {         FB.getLoginStatus(function(response) {           console.log('FB.getLoginStatus', response);         }, true);       });     });   </script>     <button id="loginButton">FB.login()</button>   <button id="logoutButton">FB.logout()</button>   <button id="getLoginStatusButton">FB.checkLoginStatus()</button> </body> </html> 

2 Answers

Answers 1

The reason this doesn't work for you on localhost is that you have set the App domains to localhost, app domains should only be set when you are using a actual domain.

So I went through a debugging session on the Javascript loaded by FB JSSDK and found below line

document.cookie = n + "=" + o + (o && p === 0 ? "" : "; expires=" + r) + "; path=/" + (q ? "; domain=" + j : "") 

When you have no App domains set then q=null and j=.localhost. So no domain is set on the cookie and hence it all works great.

When you have a App domains set as localhost, q=true and j=.localhost. So when the code tries to set domain it uses something like below

"fbsr_370363483399260=q8i_dn0F22UweXRMNff0tf5WpfYOelZ0vsjtIKrDhzw.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI....A4NTgwNzg1MzEwOTk5In0; expires=Fri, 13 Oct 2017 14:00:01 GMT; path=/; domain=.localhost"

This doesn't work on localhost and doesn't allow setting the cookie at all. document.cookie will not set any cookie not related to current page. But if I override j=localhost in console the cookies work. That is the reason you shouldn't set App domain to localhost when testing locally

FB Cookies on local

Answers 2

The method FB.logout() logs the user out of your site and, in some cases, Facebook.

This means:

  1. Steps: User not logged in Facebook -> Logins into your app

    On FB.Logout: User will log out from your app and Facebook

  2. Steps: User not logged in Facebook -> Logins into some other app. -> Logins into your app

    On FB.Logout: User will log out from both the apps and Facebook

  3. Steps: User already logged in Facebook -> Logins into your app

    On FB.Logout: User will log out from your app but not facebook.

(Note: If User is not logged in Facebook, he/she will have to first log into Facebook and then your app)

So in all cases the user has to be logged in with facebook so when you use FB.getLoginStatus following things will happen:

  1. User Logged into Facebook and your app is authenticated.

    FB.getLoginStatus returns connected

  2. User logged into Facebook but has not authenticated your application

    FB.getLoginStatus returns not_authorized

  3. Now if the user logs out of Facebook or logs out of your app (which may results in log out from Facebook). (This seems to be your case) Because in this case, the app doesn't even make an attempt to connect to facebook, that's why unknown.

    FB.getLoginStatus returns unknown

EDIT:

Now in third case it will always return unknown because it doesn't even try to connect to Facebook. So if you pass force true, it will attempt to make a ajax call to Facebook and will return you the status (should either be connected or not_authorized).

function getLoginStatus(cb, force) {   if (!Runtime.getClientID()) {     Log.warn('FB.getLoginStatus() called before calling FB.init().');     return;   }   if (cb) {     if (!force && loadState == 'loaded') {       cb({         status: Runtime.getLoginStatus(),         authResponse: getAuthResponse()       });       return;     } else {       Auth.subscribe('FB.loginStatus', cb);     }   }   if (!force && loadState == 'loading') {     return;   }   loadState = 'loading';   var lsCb = function lsCb(response) {     loadState = 'loaded';     Auth.inform('FB.loginStatus', response);     Auth.clearSubscribers('FB.loginStatus');   };   fetchLoginStatus(lsCb); } 

Above function taken from Facebook SDK will fetchLoginStatus if force is true.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment