如果用户已经登录facebook, FB登录回调函数不响应


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

我使用fb连接使用js。这是我的代码:

<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>

登录我使用:

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

的身份验证。login' in subscribe函数有一个响应处理程序,只有当用户点击fb按钮而不是已经登录到fb时才会调用,在fb窗口输入他/她的电子邮件地址和密码。而如果用户已经登录facebook,那么facebook对话框打开和关闭。然后,它不会将控制传递给响应处理程序。我在某处读到force="true"使它能够检测状态变化并调用回调函数。但我不知道该在哪里加力。我认为应该在logindiv中,是这样还是有其他方法?

感谢您的宝贵时间。

方法一:

虽然我相信DMCS已经给出了一个正确的解决问题的方法,但这里有另一种方法。使用facebook。使用自定义登录链接的登录方法。

<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>
身体标记:

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

当您点击按钮时,它将运行FB.login内部的回调函数。

方法2:

或者,使用FB登录按钮插件,您可以订阅auth.statusChange,并在响应中检查用户状态。

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

注意,如果你使用fb登录按钮插件,用户已经登录并连接到应用程序,没有登录按钮显示(阅读它在这里的文档)

我建议让Facebook为你做这些繁重的工作。请注意一些变化:指定的channelUrl;使用FB。getLoginStatus 3。删除设置cookie。4. 更改要收听的事件(以防他们在不同的窗口注销,或在其他地方关闭应用程序等)

    <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>

当您使用status:true初始化FB SDK时,它将从用户获取登录状态并存储它。从那时起,当你调用FB.getLoginStatus()它不访问获取最新的数据从FB,而是指本地存储的变量设置在FB.init()点-我认为它只刷新一次每20分钟(见https://github.com/facebook/facebook-js-sdk/commit/5b15174c7c9b9ea669499804d4a4c7d80771b036) -但是你可以强制刷新这样做:

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

这应该触发你的auth.login事件,或者你也可以将你为该事件定义的处理程序传递给FB.getLoginStatus

甚至可以更进一步,轮询这个函数,如:

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

将"status: true "更改为"status: false ",我相信它会达到您的目的。问题是status: true使状态检查发生在init上,所以当用户点击按钮时没有什么可改变的。

在下面的评论中找到了答案:http://www.bubblefoundry.com/blog/2011/03/the-facebook-login-button-and-logging-into-your-webapp/

你需要替换

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

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

作为身份验证。authStatusChange事件触发状态更改,无论是否已登录或通过提供凭据登录。

谢谢

这行得通:

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);  
});