FB login callback function not responding if user is already logged in facebook

南楼画角 提交于 2019-12-20 09:37:33

问题


I am using fb connect using js. This is my code:

<script>
    window.fbAsyncInit = function() {
      FB.init({
        appId      : 'xxxxxxxxxxxxxxxx',
        status     : true, 
        cookie     : true,
        xfbml      : true,
        oauth      : true
      });

      FB.Event.subscribe('auth.login', function(response) {
        obj=response.authResponse;
        token=obj.accessToken;
        setCookie("access_token_fb", token, '2');

        window.location.reload();
      },true);
    };
    (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.getElementsByTagName('head')[0].appendChild(js);
     }(document));
  </script>

for login I am using:

 <div class="fb-login-button" scope="email,user_checkins"  >Login with Facebook</div>

'auth.login' in subscribe function has a response handler it is only being called when user click on fb button and not already logged into FB, enter his/her email address and password in fb window . While if a user is already logged in facebook then fb dialog open and close. It doesnot then pass control to response hander. I read somewhere that force="true" enable it to detect status change and call call back function. But I don't know where to add force ture. I think it should be in login div. Is it true or is there some other approach?

thanks for you time.


回答1:


Method 1:

Though I believe that DMCS has given a correct solution to the problem, here is another way to approach. Use FB.login method with a custom login link.

<script>
window.fbAsyncInit = function() {
    FB.init({
        appId: 'YOUR-APP-ID',
        status: true,
        cookie: true,
        xfbml: true,
        oauth: true
    });
};

function facebookLogin() {
    FB.login(function(response) {
        if (response.authResponse) {
            console.log('Authenticated!');
            // location.reload(); //or do whatever you want
        } else {
            console.log('User cancelled login or did not fully authorize.');
        }
    },
    {
        scope: 'email,user_checkins'
    });
}

(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.getElementsByTagName('head')[0].appendChild(js);
} (document));
</script>

Body markup:

<div id='fb-root></div><!-- required for SDK initialization -->
<a id='fb-login' href='#' onclick='facebookLogin()'>Login with Facebook</a>

When you click on the button, it will run the callback function inside FB.login.

Method 2:

Alternatively, using FB login button plugin, you can subscribe to auth.statusChange and check for the status of the user in response.

FB.Event.subscribe('auth.statusChange', function(response) {
  // check for status in the response
});

Note if you are using fb login button plugin, and the user is already logged in and connected to the app, no login button is shown (read it in the documentation here)




回答2:


I'd suggest letting Facebook do the heavy lifting for you. Please note some changes: 1. channelUrl specified, 2. use of FB.getLoginStatus 3. removal of setting a cookie. 4. change of event to listen to (so in case they log out in a different window, or deauth your app elsewhere, etc )

    <script>
        window.fbAsyncInit = function() {
        FB.init({
            appId      : 'xxxxxxxxxxxxxxxx',
            status     : true, 
            cookie     : true,
            xfbml      : true,
            oauth      : true,
            channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html' // Channel File
        });

        FB.getLoginStatus(function(response) {
            if (response.status === 'connected') {

                var uid = response.authResponse.userID;
                var accessToken = response.authResponse.accessToken;

                // Do something with the access token


            } else {
                // Subscribe to the event 'auth.authResponseChange' and wait for the user to autenticate
                FB.Event.subscribe('auth.authResponseChange', function(response) {
                    // nothing more needed than to reload the page
                    window.location.reload();
                },true);      

                // now dynamically show the login plugin
                $('#mydiv').show();      
            }
        });


        };
        (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.getElementsByTagName('head')[0].appendChild(js);
        }(document));
  </script>



回答3:


When you intialize the FB SDK with status:true it will fetch the login status from the user and store it. From that point on when you make calls to FB.getLoginStatus() it isnt accessing fetching the latest data from FB but is instead referring to the locally stored variables that were set at the point of FB.init() - I think its only refreshed once every 20 mins (see https://github.com/facebook/facebook-js-sdk/commit/5b15174c7c9b9ea669499804d4a4c7d80771b036) - however you can force the refresh by doing this:

FB.getLoginStatus(function() {...}, /*FORCE*/ true);

This should then fire your auth.login event or you could just pass the handler you defined for that event to FB.getLoginStatus as well.

Can even go a set further and poll this function like:

setTimeout(function() {
    FB.getLoginStatus(function() {...}, /*FORCE*/ true);
}, 10000); // poll every 10 seconds



回答4:


Change from "status : true," to "status : false," and I believe it'll do what you want. The problem is status : true makes the status check happen on init, so there is nothing to change when the user clicks the button.

Found the answer on next-to-last comment here: http://www.bubblefoundry.com/blog/2011/03/the-facebook-login-button-and-logging-into-your-webapp/




回答5:


You need to replace

FB.Event.subscribe('auth.authResponseChange', function(response){     

with

FB.Event.subscribe('auth.statusChange', function(response){ 

As auth.authStatusChange event trigger on status change whether already logged in or login by giving credentials.

thanks




回答6:


This works:

FB.getLoginStatus(function(response) {
//only works when page loads, use FB.Event.subscribe for status change      
    statusChangeCallback(response);
    FB.Event.subscribe('auth.statusChange', function(response){
        //yay! do whatever here, there was a status change
    },true);  

});


来源:https://stackoverflow.com/questions/8541162/fb-login-callback-function-not-responding-if-user-is-already-logged-in-facebook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!