Функция обратного вызова для входа в FB не отвечает, если пользователь уже вошел в систему facebook

Я использую fb connect с помощью 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>

'auth.login' в функции подписки имеет обработчик ответа, который вызывается только тогда, когда пользователь нажимает кнопку fb и еще не вошел в FB, введите свой адрес электронной почты и пароль в окне fb. Хотя, если пользователь уже вошел в систему facebook, диалоговое окно fb открывается и закрывается. Затем он не передает управление обработчику ответов. Я где-то читал, что force="true" позволяет обнаруживать изменение статуса и вызывать функцию обратного вызова. Но я не знаю, куда добавить силу. Я думаю, что это должно быть в разделе входа в систему. Это правда или есть какой-то другой подход?

спасибо за ваше время.


person Hafiz    schedule 16.12.2011    source источник
comment
У меня такая же проблема. Я заметил, что если это пользователь, связанный с приложением, он показывает это поведение. Пожалуйста помоги.   -  person Somnath Muluk    schedule 04.01.2012
comment
Я хочу вызвать событие (так же, как событие после входа в систему) после нажатия кнопки входа в систему, если все готовы войти в систему пользователя приложения.   -  person Somnath Muluk    schedule 05.01.2012
comment
@SomnathMuluk Поскольку вы, похоже, используете плагин входа в систему fb, если пользователь вошел в систему и уже подключился к вашему приложению, кнопка входа не будет отображаться (прочитайте там примечание). Вы можете подписаться на событие auth.statusChange с помощью пользовательской кнопки, если хотите это сделать. Объяснил это в моем ответе.   -  person Jai Pandya    schedule 06.01.2012
comment
У меня такая же проблема. И несмотря на то, что говорится в документации, эта кнопка входа всегда отображается на моем сайте, даже если пользователь уже вошел в систему. У меня нет проблем с постоянно отображаемой кнопкой. Но если пользователь выходит из моего сайта, а затем хочет снова войти с помощью кнопки входа в FB, он не может, потому что кнопка, похоже, ничего не делает.   -  person East of Nowhere    schedule 14.02.2012
comment
@EastofNowhere задайте другой вопрос с вашим кодом, который вы используете, а затем разместите ссылку на этот вопрос здесь, чтобы мы могли увидеть ваш код и рассказать вам лучше   -  person Hafiz    schedule 15.02.2012


Ответы (6)


Способ 1:

Хотя я считаю, что DMCS дала правильное решение проблемы, есть еще один подход. Используйте метод FB.login с пользовательской ссылкой для входа.

<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, а пользователь уже вошел в систему и подключился к приложению, кнопка входа не отображается (см. документацию здесь)

person Jai Pandya    schedule 05.01.2012
comment
Ваш 1-й метод решил мою проблему. Я вызвал функцию facebookLogin() при нажатии пользовательской кнопки входа. Спасибо. - person Somnath Muluk; 10.01.2012
comment
Да, 1-й метод сделал это для меня. Спасибо! - person Ervi B; 06.07.2012

Я бы предложил, чтобы Facebook сделал всю тяжелую работу за вас. Обратите внимание на некоторые изменения: 1. указан channelUrl, 2. использование 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>
person DMCS    schedule 04.01.2012
comment
Это вызовет после загрузки страницы. Я хочу позвонить после нажатия кнопки входа. - person Somnath Muluk; 05.01.2012
comment
Он будет вызываться при нажатии кнопки входа. См. метод FB.Event.Subscribe. Опять же, этот способ заключается в том, чтобы позволить фреймворку выполнять тяжелую работу, и он также следует вашему требованию 'auth.login' в функции подписки, имеет обработчик ответа, который вызывается только тогда, когда пользователь нажимает кнопку fb, а не еще авторизовался в ФБ - person DMCS; 08.01.2012

Когда вы инициализируете FB SDK с помощью status:true, он получит статус входа в систему от пользователя и сохранит его. С этого момента, когда вы делаете вызовы FB.getLoginStatus(), он не получает доступ к получению последних данных из FB, а вместо этого ссылается на локально сохраненные переменные, которые были установлены в точке FB.init() - я думаю, что он обновляется только один раз каждые 20 минут (см. https://github.com/facebook/facebook-js-sdk/commit/5b15174c7c9b9ea669499804d4a444 a>) - однако вы можете принудительно обновить, выполнив следующие действия:

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

Затем это должно запустить ваше событие auth.login, или вы можете просто передать обработчик, который вы определили для этого события, также в FB.getLoginStatus.

Можно даже пойти дальше и опросить эту функцию, например:

setTimeout(function() {
    FB.getLoginStatus(function() {...}, /*FORCE*/ true);
}, 10000); // poll every 10 seconds
person nav    schedule 04.01.2012
comment
Я получаю статус входа в систему хорошо. Хотя, если пользователь уже вошел в систему facebook, диалоговое окно fb открывается и закрывается. Затем он не передает управление обработчику ответа после нажатия кнопки входа в систему. - person Somnath Muluk; 05.01.2012

Измените «статус: истина» на «статус: ложь», и я верю, что это сделает то, что вы хотите. Проблема в status : true делает проверку состояния при инициализации, поэтому ничего не меняется, когда пользователь нажимает кнопку.

Нашел ответ на предпоследний комментарий здесь: http://www.bubblefoundry.com/blog/2011/03/the-facebook-login-button-and-logging-into-your-webapp/

person Guy Goldstein    schedule 28.03.2013
comment
Честно говоря, я не тестировал ваш код, и, к вашему сведению, я использую эту строку, поэтому вы можете попробовать, если по какой-то причине это не исправит: FB.Event.subscribe('auth.statusChange', .. .) - person Guy Goldstein; 28.03.2013

Вам нужно заменить

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

с участием

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

Поскольку событие auth.authStatusChange срабатывает при изменении статуса, независимо от того, вошли ли вы в систему или вошли, предоставив учетные данные.

Благодарность

person Hafiz    schedule 05.01.2012
comment
Всякий раз, когда я загружаю страницу входа, она будет напрямую перенаправляться на мою функцию. Я хочу, чтобы после нажатия кнопки входа он перешел к моей функции. - person Somnath Muluk; 08.01.2012
comment
@SomnathMuluk См. это: developers.facebook.com/docs/reference/ javascript/ Это просто событие, которое запускается при любом изменении статуса, вам решать, как вы его используете, в auth.statusChange есть статус, который может быть подключен, авторизован или неизвестен, см. Полную информацию по ссылке выше. - person Hafiz; 08.01.2012

Это работает:

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

});
person Clinton J Calhoun    schedule 19.08.2016