Facebook getLoginStatus return function not firing when page refresh - facebook

I'm using Facebook Javascript SDK. For my app, I can have a user either login using Facebook, Twitter, or an account (email/password). I can get Facebook authentication to work. After successful Facebook authentication, I create a user session and the user proceeds to use the app. I have a logout button in the app that destroys the session and sends user back to the login page.
When the user lands back on login page, they are still connected to Facebook. I've tried calling FB.logout but the return function for getLoginStatus never fires. What am I doing wrong?
Here's my code:
window.fbAsyncInit = function()
{
FB.init({appId: 99999999, status: true, cookie: true, xfbml: true, oauth: true});
//LOGOUT FB USER
FB.getLoginStatus(function(response)
{
alert("status: " + response.status);
if (response.authResponse)
{
FB.logout();
alert('logged out');
}
}, true);
//SUBSCRIBE TO LOGIN EVENT
FB.Event.subscribe('auth.login', function(response)
{
if(response.authResponse)
{
FB.api('/me', function(response)
{
//at this point user has been authenticated so they can continue with app...
});
}
else
{
alert("Ooops, the Facebook authentication has failed. Please try again.");
}
});
};
(function(d){
var js, id = 'facebook-jssdk';
if (d.getElementById(id)){ return; }
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementById('fb-root').appendChild(js);
}(document));
What are the best practices around incorporating Facebook authentication into your app? How do you manage logging user out of your app without logging them out of facebook altogether?
Thanks for your time.

Sorry, I misunderstood your question.
The FB SDKs only supports logging out from FB, and then you can use the callback for logging the user out from your own site.
In this case you want to logout the user from your own site but not FB - then you should not use the SDK for logout, as this is used to logout the user from FB.
Instead you will have to make some kind of "reverted" login system.
If the user logs in with FB then set a session/cookie "mySiteLogin".
When checking for authorization, check both the FB-login AND "mySiteLogin".
When the user clicks logout unset/delete "mySiteLogin".
This is just a solution of the top of my head. But I too was not able to find any out-of-the-box solution.

There's three things that are all trying to do something with login
status: true
FB.getLoginStatus(function(response)
FB.Event.subscribe('auth.login'
When status is set to true, the SDK will call facebook to see if the current user is authenticated. Then you also have a check again of getLoginStatus and then while that is running async, you subscribe to the auth.login.
auth.login will be called even from the status: true call and possibly again from the getLoginStatus call.
Instead of doing alerts which interrupt the flow, do console.logs so you can see what's being called when.
As for this question: "I do not want to log them out of facebook from my app. Is this even possible?"
Yes, you can log the user out of your app by sending an HTTP DELETE to me/permissions with that user's valid access token. This will force them to reauth your app the next time. It's about the only effective way I know of to get them "out of my app" but not log them out of their facebook session.

Related

FacebookJavaScriptLoginHelper fails to authenticate user on first page refresh

I'm creating a Facebook app for mobile devices. Such application is displayed within a mobile browser, unlike Facebook canvas pages which are held in an iframe.
I'm using a mix of JS and PHP SDK to authorize and authenticate a user. The user needs to be already logged into Facebook to use my app. If not, they need to log in with Facebook login button. As a bridge between JS and PHP SDKs I'm using FacebookJavaScriptLoginHelper.
Part of my Facebook.php library doing the job:
<?php
// Initialize the SDK
FacebookSession::setDefaultApplication($this->app_id, $this->app_secret);
// Create the login helper
$this->helper = new FacebookJavaScriptLoginHelper();
try {
$this->session = $this->helper->getSession();
} catch(FacebookRequestException $ex) {
// When Facebook returns an error
} catch(Exception $ex) {
// When validation fails or other local issues
}
if ($this->session) {
// User logged in
$this->session = new FacebookSession($this->session->getToken());
}
?>
Facebook JS init:
<script type="text/javascript">
window.fbAsyncInit = function() {
FB.init({
appId: '{my app id}',
status: true,
xfbml: true,
cookie: true
});
}
FB.getLoginStatus(function(response) {
console.dir(response);
});
</script>
The above code works fine but there's a specific case when it fails. Let's assume I have two tabs open in my browser: in the first tab I have my app open, in the second one - I'm logged into Facebook. Two scenarios can take place:
I log out of Facebook and refresh the tab with my app. The result is correct:
FacebookSession is NULL
response.status from FB.getLoginStatus is 'unknown'. The user is not
logged in.
I go to the second tab, log back into Facebook and refresh the first tab with my app. The result is incorrect, but only on the first refresh:
FacebookSession is still NULL, even if
response.status of FB.getLoginStatus is 'connected'
The reason behind this fail on first refresh seems to be obvious: In the moment of reloading the page PHP SDK is triggered before Facebook cookie is refreshed. However, it's never a problem when the user logs out - in this case, somehow FacebookSession is updated instantly, as expected.
How come it does not work the same when the user logs into Facebook?
Does this help?
Subsequent calls to FB.getLoginStatus will return data from this cached response. This can cause problems where the user has logged into (or out of) Facebook since the last full session lookup, or if the user has removed your application in their account settings.
To get around this, you call FB.getLoginStatus with the second parameter set to true to force a roundtrip to Facebook - effectively refreshing the cache of the response object.
FB.getLoginStatus(function(response) {
// this will be called when the roundtrip to Facebook has completed
}, true);
Source: https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus
Section: Roundtrips to Facebook's servers

Chrome blocks FB.login()

I have a FB app which need to be integrated in a FB page tab. In app I want to provide a "Signup with FB login" option. This button when clicked should prompt the user to login into FB login dialog. On successful login it should prompt the user to authenticate and allow the app to use his details. Once the user allows the app to access the user details it should then post the details to my website in a new window.
This process works fine when I test the app independently. However when I add the app to the fb page, chrome blocks the Fb login dialog. Before opening the Fb login dialog I check if the user is already logged in FB and has accepted the app. For that I use FB.getLoginStatus(checkLoginStatus); I figured due to this check the context moves to script execution and hence Chrome blocks the login dialog.
Is there a work around for this issue? Help would be highly appreciated.
My code is as follows:
The facebook button is created using span and the id fbc-login-button is given to an a tag.
$("#fbc-login-button").click(function(){
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
console.log('Logged in.');
if (response.authResponse) {
fbAppSignup(response);
}
}
else {
FB.login(function(response) {
if (response.authResponse) {
fbAppSignup(response);
}
},{scope: "email, user_friends",display:"popup"});
}
});
function fbAppSignup(response,myPopup){
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
FB.api("/me", function(response) {
$("#social_media_data").val(JSON.stringify(response));
$("#medium").val("facebook");
$("#accessToken").val(accessToken);
$("#socialClickSource").val("fbapp_facebook_signup");
$("#fbSignUp").submit();
return true;
});
}
The example in the Facebook docs is a bit misleading, you should never use FB.login in an asynchronous callback function - and that is exactly what you are doing right now, because FB.getLoginStatus is asynchronous. Always call FB.login on user interaction (mouse click) or it will get blocked by intelligent browsers.
FB.getLoginStatus: on page load, for refreshing the user session and
checking if the user is authorized already
FB.login: on user interaction
Other threads i´ve answered about that problem:
Facebook login popup blocked
FB.api response callback async popup blocked
Sign In with FB issue: FB popup window with the Login dialog is blocked by a web browser

Facebook Kiosk Logout

We have a facebook website app for use as a public event kiosk. Many people will be logging into facebook through our site on the same device (set up at a booth, like a ipad or similar).
We need to log the person out of facebook itself after they are done; not simply destroy the graph api session for our site.
Here is the problem:
User walks up to our ipad, which has a browser loaded to our website. He or she clicks "facbook login", and is redirected to facebook to log in.
They log in, grant our app permission, and facebook redirects them back to our site.
After they use our site (post comment, etc...) they click log out on our site.
Next user sits down, clicks "facebook login", and is redirected to facebook. Upon reaching facebook.com, the browser is still logged in for the previous user, granting this user access to the first user's facebook (just a small problem =)
My hope is that I can send the user to facebook, to a page with nothing but a logout button, and have facebook redirect the browser back to my site, ready for the next user. This is how the login works, and I need a logout equivalent.
Edit:
Thank you very much for the answer. We spent like 3 days trying to figure this out; I hope you will forgive us if we post generic code that anyone can plug in. Placing this on an HTML page, then visiting that page, logs the user out of Facebook and your site.
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'your APP ID', // App ID
channelUrl : '//WWW.YOURSITE.COM/channel.php or channel.html or whatever yours is', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional initialization code here
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
FB.logout();
alert('Thanks! You have been logged out of facebook.');
}
});
};
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
If you use the Facebook Javascript SDK, you can call FB.logout when they click your logout link as the documentation states:
FB.logout will log the user out of both your site and Facebook.

Facebook Connect for the website - database connection and logic

I am trying to let the users login to my website using their Facebook account. I have tried reading some information related to the process from Facebook developers (http://developers.facebook.com/docs/) page - while the process and the logic sort of make sense, I am still lost regarding the big picture.
How does 'Facebook connect' link to my existing database of users and their attributes. Say there is a user called John Walker, who is a registered user (login: jwalker pass:1234 account balance:$10). When he will come to the website, and try to login using Facebook login, how would it know where to direct him? In other words, how will Facebook know that it is the right John Walker, and he should be sent to his user page?
I am sorry if this question is trivial, but I just can't think it though myself. Thanks for your help in advance!
Zachary
Well Zachary, you have a little bit misconception regarding to facebook connect. When a user clicks on facebook connect button placed on your site, facebook doesn't go to your database to authenticate the user. He authenticates the user in his database that whether the current user is having a facebook account or not... If he/she is having account then facebook issues an access token to you for that particular user by loging him to facebook. Then its now your responsibility to login that user in your system and putting his information to your database. Let me explain more and see the following code
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({appId: "Your APP ID",
status: true,
cookie: true,
xfbml: true});
FB.getLoginStatus(function(response) {
if (response.session) {
// This is the place where you get control when user is login to facebook
// At this point you can redirect the user to a page where you can put the facebook returned information to database and login him into your system
} else {
}
});
FB.Event.subscribe("auth.login", function(response) {
window.location.reload();
});
FB.Event.subscribe("auth.logout", function(response) {
self.location.href="http://www.iranibash.com/logout.php";
});
};
(function() {
var e = document.createElement("script");
e.src = document.location.protocol + "//connect.facebook.net/en_US/all.js";
e.async = true;
document.getElementById("fb-root").appendChild(e);
}());
</script>
Now you can use the information about user that facebook returns you after successfull login. You can have that information in a $cookie. I think you can understand from this information?

Facebook Connect disable auto login

I integrated the graph api facebook connect but if we are login to facebook, we will automatically login to the site with facebook connect as well. Is there any way we let the user clicks on fb "Login" only then the user is connected to the site with their fb account?
Now the user is automatically login to the site without the option to choose whether they would want to use their facebook account. If they want to logout from the site, they need to logout from facebook completely only then they can logout from the site with facebook connect as well.
Anyone can help me or give some tips how to go about?
Thank you!
I had this same problem on a recent website, and found a way to overcome it. My solution allowed a user to already be logged into facebook on their computer, yet not have it auto login on my website, then they can login with Facebook Login button and finally when they logout it won't log them out of Facebook on their computer, just on my website (much like Digg does with facebook).
To do it I was using https://github.com/facebook/php-sdk/ to check within PHP if there was an active facebook session with the user and the website (which would cause the auto login). If there was, I would not echo the auto login code:
FB.init({
appId : '<?php echo $facebook->getAppId(); ?>',
session : <?php echo json_encode($session); ?>, // don't refetch the session when PHP already has it
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
FB.Event.subscribe('auth.login', function() {
window.location = "process-login.php";
});
but instead just render my own facebook login button that would link to "process-login.php".
process-login.php would set the custom $_SESSION variable that told my website someone was logged (whether via my own system, or via facebook), and then reload the referring page (using $_SERVER['HTTP_REFERER']) which would now display the user as logged in via Facebook since my own $_SESSION variable was now set. To log them out (without logging them out of Facebook entirely, just my website), I would just load a logout script that removed the $_SESSION variable.
The example.php (in the php-sdk on github) was very helpful at finding my solution, though I had to customise it significantly to make it work with my existing system. It at least helped me see how to access the facebook session variable in PHP (stored in $me in the example).
Hope this helps you if its still a problem, or that it helps someone else in this situation.
EDIT:
Turns out I still had some issues with auto login on the rare occasion. To fix it I removed the event.subscribe('auth.login') and make a facebook button that called the following function to check login status before subscribing to the auth.login even. Here is the function:
function check_login_session(){
FB.getLoginStatus(function(r){
if(r.session){
window.location = '/process-login.php';
}
else{
FB.Event.subscribe('auth.login', function(response) {
window.location = '/process-login.php';
});
FB.login();
}
});
}`
I had the same problem, I guess that you are using the scripts provided by facebook. In that case you have a function associated with the window.fbAsyncInit event. This happens everytime that the page is loaded.
At the end of this method you have the code:
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
The function statusChangeCallback verifies your user's facebook status (connected, authorized, or unknown). Here, if the user is "connected" you log him into your site. Well that's the problem, you are always trying to log the user in with facebook.
This must only happen on click, so you should erase those lines
hello dear I think you have made your question so confused. Your question is not stating what actually do you want. As for as I have understood I think you want to connect the user to you site through facebook connect and you want when user clicks on facebook logout, it automatically logouts from your site.
if my understanding about your question is right then simply let the user to login through facebook and do logins in your system in FB.Event.Subscribe event.
Use the following code for login button
<fb:login-button perms='email' autologoutlink='true'>
When user will allow your his facebook account to connect with your site
<div id="fb-root">
<script>
window.fbAsyncInit = function() {
FB.init({appId: "Your APP ID",
status: true,
cookie: true,
xfbml: true});
FB.getLoginStatus(function(response) {
if (response.session) {
// Send here parameters that logins to your system through your website login system
} else {
}
});
FB.Event.subscribe("auth.login", function(response) {
window.location.reload();
});
FB.Event.subscribe("auth.logout", function(response) {
window.location.reload();
//Send the Parameters that logouts user from your website through your website logout system;
});
};
(function() {
var e = document.createElement("script");
e.type = "text/javascript";
e.src = document.location.protocol +
"//connect.facebook.net/en_US/all.js";
e.async = true;
document.getElementById("fb-root").appendChild(e);
}());
and put the above whole code right after your <body> tag
If You have:
FB.Event.subscribe('auth.login', function() {
fbLogin(this);
});
Try to comment it /* fb.Event..... */