auth.authResponseChange event callback fires when FB.getLoginStatus() is called? - javascript

I am trying to implement the FB JS SDK on my website, both for logging in and also for sharing/liking content.
Here is my code:
// called by FB SDK once loaded (all.js)
window.fbAsyncInit = function () {
FB.init({
appId : '913550365396947',
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse social plugins on this page
version: 'v2.5',
status: false // don't check login status
});
FB.getLoginStatus(function (response) {
console.log('FB.getLoginStatus callback response', response);
});
// auth.authResponseChange event is fired for any authentication related change, such as login, logout or session refresh
FB.Event.subscribe('auth.authResponseChange', function (response) {
console.log('auth.authResponseChange callback response: ', response);
// Here we specify what we do with the response anytime this event occurs.
if (response.status === 'connected') {
if (!shopWise.loggedIn) { // if the user isn't logged in to PW, but they are logged in to facebook
console.warn('Logged in with facebook, but not logged in to shopwise. Reloading the page..');
location.reload();
}
} else if (response.status === 'not_authorized') {
} else {
}
});
};
The problem I'm having is that the auth.authResponseChange callback is being executed on every page load, while (if my understanding is correct) it should only be executed when the user's login state actually changes (such as logging in, or logging out).
Because the event is called on every page load, my page refresh code is executed on every page load, which means the page is in an endless refresh loop.
What's strange is that if I remove the FB.getLoginStatus() call, the auth.authResponseChange callback is not fired.
What am I doing wrong here? Why is calling FB.getLoginStatus() causing the auth.authResponseChange callback to be fired?

Related

Refreshing FB Access Token with Javascript SDK

For context I am trying to build a small microsite to pull social media insights from Facebook. I am looking to build a Django backend and React front end.
I would like to implement FB login with the Javascript SDK since according to the docs this refreshes the access token each time a FB call is made using the SDK.
I have a very simple login script taken from FB official docs which literally just logs in the user and then outputs the list of accounts the user has access to.
The issue is that, despite refreshing the page (and therefore performing an API request) the data expiration date doesn’t extend (it still displays the date of first login).
Is anyone familiar with the Javascript SDK and whether this is normal behaviour?
function statusChangeCallback(response) { // Called with the results from FB.getLoginStatus().
console.log(response);
if (response.status === 'connected') { // Logged into your webpage and Facebook.
testAPI();
FB.getAuthResponse(function(response){
console.log(response.authResponse.accessToken);
});
} else { // Not logged into your webpage or we are unable to tell.
document.getElementById('status').innerHTML = 'Please log ' +
'into this webpage.';
}
}
function checkLoginState() { // Called when a person is finished with the Login Button.
FB.getLoginStatus(function(response) { // See the onlogin handler
statusChangeCallback(response);
});
}
window.fbAsyncInit = function() {
FB.init({
appId : 'APP_ID_GOES_HERE',
cookie : true, // Enable cookies to allow the server to access the session.
xfbml : true, // Parse social plugins on this webpage.
version : 'v13.0' // Use this Graph API version for this call.
});
FB.getLoginStatus(function(response) { // Called after the JS SDK has been initialized.
statusChangeCallback(response); // Returns the login status.
});
};
function testAPI() { // Testing Graph API after login. See statusChangeCallback() for when this call is made.
console.log('Welcome! Fetching your information.... ');
FB.api('/me/accounts',
function(response) {
console.log(response)
});
}
function logout_js_user(){
FB.logout(function(response) {
// Person is now logged out
});
};
FB.getLoginStatus does refresh the Token, but not on every Page call. It only refreshes the Token when it is not valid anymore. That is why the expiration data does not change.
You can can a more accurate status with the second parameter of the function set to true, but be aware that this might affect performance:
FB.getLoginStatus(function(response) {
// this will be called when the roundtrip to Facebook has completed
}, true);
If you call FB.getLoginStatus on every page load, be careful not to
set this parameter for each as it will significantly increase the
number of requests to Facebook's servers, and thus decrease the
performance of your application.
Side note: ou can use FB.login to make the login less complicated (in my opinion) - here's an old but still valid article about that: https://www.devils-heaven.com/facebook-javascript-sdk-login/

Facebook callback right after opening the Oauth popup

I'm using the login flow suggested by the fb documentation;
Html
Click me to login!
JavaScript
//USER WANTS TO LOGIN
$("a").click(function() {
FB.login( checkLoginState(), { scope: 'email,user_birthday,user_likes' });
})
//CALLBACK LISTENER OF WHAT THE USER CHOOSE
function checkLoginState(mode) {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
//WHAT TO DO DEPENDING ON WHAT THE USER CHOOSE
function statusChangeCallback(response) {
if (response.status === 'connected') {
//LIFE IS GOOD
alert("Thank you, know my php script will handle the rest");
} else if(response.status == 'not_authorized') {
//THE USER DOES NOT AUTHORIZE
alert("Im sorry, you have to authorize the app in order to proceed");
}
}
The problem is, when I call FB.login, the popup opens as it should asking the user to login or authorize my app, BUT, as soon as the popup opens the statusChangeCallback is called giving me an status. I don't get why the SDK is giving me a callback as soon as it opens, the user needs to "say something" (login, or authorize or not the app) in order to trigger a response. You see, with this flow, as soon as the user clicks the login button the alert Im sorry, you have to authorize the app in order to proceed will popup. Also, worst, is the fact that when the user introduce its credentials in the popup and authorize the app, there is no callback...
What am i missing?
checkLoginState needs to be passed int FB.login() as a function. You are calling it.
your click event binder should look like this:
$("a").click(function() {
FB.login( checkLoginState, { scope: 'email,user_birthday,user_likes' });
})
Please make the below change and try.
//USER WANTS TO LOGIN
$("a").click(function() {
FB.login( checkLoginState, { scope: 'email,user_birthday,user_likes' });
})
//CALLBACK LISTENER OF WHAT THE USER CHOOSE
var checkLoginState=function() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
//WHAT TO DO DEPENDING ON WHAT THE USER CHOOSE
function statusChangeCallback(response) {
if (response.status === 'connected') {
//LIFE IS GOOD
alert("Thank you, know my php script will handle the rest");
} else if(response.status == 'not_authorized') {
//THE USER DOES NOT AUTHORIZE
alert("Im sorry, you have to authorize the app in order to proceed");
}
}

how to detect log out from fb using JS SDK without refreshing the page

Hi friends,
I'm developing a website in which Facebook Javascript API is used to send message to our friends.
When the user is logged out of fb,then it shows an error when popping up js API dialog box which is
"Refused to display 'https://www.facebook.com/login.php?api_key=0&skip_api_login=1&display=dialo…cale%3Den_US%26name%3DAnything%26to%3D1791715188%26from_login%3D1&rcount=1' in a frame because it set 'X-Frame-Options' to 'DENY'."
Currenty,I'm using FB.getLoginStatus to detect whether the user is logged out or not. But this will work for only first time,I can't dynamically check it(That means when I logged out of fb account and coming back to the same window and trying to send next message without refresh,it shows the above error.).
Here How Can I dynamically detect that the user is currently logged out. Is there any way to checking FB.getLoginStatus dynamically without page refresh.
I'm showing my code below.
$(document).ready(function(){
window.fbAsyncInit = function() {
FB.init({appId: '**************', xfbml: true, cookie: true,status:true,oauth:true});
/*FB.Event.subscribe('auth.login', function() {
//window.location.reload();
});*/
FB.Event.subscribe('auth.logout', function(response) {
alert('logged out!');
});
};
function facebook_send_message(to,name) { //function called when a button is clicked
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
console.log('how to check');
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
send_message(to,name);
}
else if (response.status === 'not_authorized') {
console.log('not_authorized');
// the user is logged in to Facebook,
// but has not authenticated your app
}
else
{
console.log('hi');
FB.login(function(response) {
if (response.authResponse)
{
send_message(to,name);
//getUserInfo(); // Get User Information.
} else
{
console.log('Authorization failed.');
}
},{scope: 'email'});
}
});
}
send_message(to,name); will send message if user is logged in,
Currently for the first time,it works clearly,but from the second time without page refresh and if we logged out from fb, then FB.getLoginStatus still shows response.status as 'connected' and hence error occured.
Waiting for your kind replies.
Thanks in Advance
According to Facebook,
https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
To improve the performance of your application, not every call to check the status of the user will result in request to Facebook's servers. Where possible, the response is cached. The first time in the current browser session that FB.getLoginStatus is called, or the JS SDK is init'd with status: true, the response object will be cached by the SDK. 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);

Facebook login silently failing

I'm trying to implement login to a website with Facebook, using their JavaScript SDK. I understand that this is OAuth 2 under the hood, although that shouldn't even matter... I am setting things up using the async loader, and the FB variable exists and I can call functions in it. When I call FB.login(), another tab opens, flashes for a fraction of a second, and then closes. I then wind up back on my page, with no events having been triggered and no sign that anything has happened.
I have initialized the API as follows:
FB.init({
appId : facebookAppID,
channelUrl : channelFilePath,
status : true,
xfbml : true
});
FB.Event.subscribe('auth.authResponseChange', function(response) {
if (response.status === 'connected') {
console.log("Connected.");
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
});
} else if (response.status === 'not_authorized') {
console.log("Not logged in.");
} else {
console.log("Still not logged in.");
}
});
Then my login call is simply:
function loginFacebook() {
console.log("Trying to log in.");
FB.login();
}
One detail which might be relevant is that I'm running for development purposes on a nonstandard port, 1980 instead of 80. It's not easy for me to try port 80, because of where I'm running, but if it turns out to be the problem I absolutely can.
Thanks in advance. :)
It turned out to be the port. Yes - they check, apparently! The completely silent failure was really perplexing...

Can't get FB.getLoginStatus to run

EDIT: It turns out I am not very intelligent. I should have checked first thing if my partner changed the settings of the FB app... which he did. I think he actually mentioned it to me as well. Ah, the importance of communication. Sorry to the people who answered my question.
Here's the code I have. The following will print out the BALH and the BALefefH but not "response". There's no error on the console.
$(document).ready(function(){
console.log("BALH");
var myID;
var access_token;
FB.init({
appId : NUMBER,
status : true,
cookie : true,
xfbml : true,
});
console.log("BALefefH");
FB.getLoginStatus(function(response) {
console.log("response");
if(!response.session) {
FB.login(function(response) {
myId = response.session.uid;
access_token = response.session.access_token;
beginStuff(myId, access_token);
if (!response.session) {
console.log('User cancelled login or did not fully authorize.');
}
});
}
else if(response.session) {
myId = response.session.uid;
access_token = response.session.access_token;
beginStuff(myId, access_token);
}
});
});
Are you loading the sdk asynchronously? If you are loading it asynchronously, you should put all calls to FB within a window.fbAsyncInit function. This is called once the sdk has finished loading and will ensure that FB is defined.
Also make sure if you aren't loading asynchronously that you are loading it before this script runs. So if you are including both the fb js sdk and your snippet above, make sure the fb js sdk is first.

Categories

Resources