Функция обратного вызова FB login не отвечает, если пользователь уже вошел в 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" позволяет обнаруживать изменение состояния и вызывать функцию обратного вызова. Но я не знаю, куда добавить силу. Я думаю, что это должно быть в login div. Это правда или есть какой-то другой подход?
спасибо за ваше время.
6 ответов
Способ 1:
хотя я считаю, что DMCS дал правильное решение проблемы, вот еще один способ подхода. Используйте FB.метод входа с пользовательской ссылкой входа.
<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.авторизоваться.
Способ 2:
кроме того, используя плагин FB login button, вы можете подписаться на auth.statusChange
и проверить для статуса пользователя в ответ.
FB.Event.subscribe('auth.statusChange', function(response) {
// check for status in the response
});
Примечание Если вы используете плагин FB login button, и пользователь уже вошел в систему и подключен к приложению, кнопка входа не отображается (прочитайте ее в документации здесь)
Я бы предложил позволить 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>
когда вы intialize FB SDK с status:true
он получит статус входа в систему от пользователя и сохранит его. С этого момента, когда вы делаете звонки 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
измените " статус: true "на" статус : false", и я считаю, что он будет делать то, что вы хотите. Проблема в статусе: 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){
Как auth.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);
});