Вход в Google+ с вызовом обратного вызова JavaScript

Я работаю над функцией, которая позволяет пользователям регистрироваться на моем сайте со своей учетной записью Google.

Мой код основан на документации Google (другие параметры signIn() находятся в метатегах).

function login() {
  gapi.auth.signIn({'callback':
    function (authResult) {
      if (authResult['status']['signed_in']) {
        console.log('Okay');
      }else {
        console.log('Error');
      }
    }
  });
}

Когда я вызываю login(), появляется всплывающее окно Google, я одобряю условия моего приложения, и все работает нормально.

Но обратный вызов вызывается дважды:

  • 1-й случай: если я никогда не одобрял разрешения приложений, тогда обратный вызов будет вызван при открытии всплывающего окна И когда я буду одобрять разрешения. Поэтому он будет писать "Ошибка" и "Хорошо".
  • Второй случай: если я уже одобрил разрешения, он будет писать "Хорошо" два раза.

Я добавил функцию 'approvalprompt': 'force' в функцию signIn(). Функция обратного вызова больше не вызывается дважды, но заставляет пользователя утверждать разрешения приложений, даже если они были одобрены ранее. Так что это не удобно.

Есть ли у пользователя удобный способ одобрить разрешения приложений один раз без двух обратных вызовов?

Спасибо.

Ответ 1

Я столкнулся с этой же проблемой здесь, но я вызываю gapi.auth.signIn() с помощью обработчика щелчка. Обратный вызов по-прежнему вызывается дважды. Одна вещь, которую я заметил между двумя объектами authResult, заключалась в том, что authResult.status.method является "АВТО" при первом вызове (перед всплывающим окном) и является "PROMPT" во втором вызове после автоматического отклонения окна из-за предыдущего авторизации.

Решение, которое я сейчас изучаю, - это игнорировать экземпляр AUTO и обрабатывать только экземпляр PROMPT обратного вызова. Не знаете, как это будет работать после отмены прав в Google из-за отсутствия деталей в документах объекта "status".

Ответ 2

Я столкнулся с одной и той же проблемой: callin callback дважды вызывается в случае, если пользователь уже предоставил разрешение; метод local variable (initializedGoogleCallback) не работает для меня, потому что он вызывает обратный вызов один раз только тогда, когда пользователь уже предоставил доступ, но не вызвал его, если пользователь является новым. После небольшого исследования (я особенно раскопал сайт, используя g + auth), я заметил, что все они используют 'approvalprompt': 'force', и у них есть уже предоставленный пользователь, чтобы каждый раз повторно одобрять политику автономного доступа. Даже пример Google, который я выполнил для настройки моего приложения (https://developers.google.com/+/web/signin/javascript-flow), даже если он не упоминал об этом, он использует параметр "force". На данный момент это кажется единственным решением, если вы хотите использовать поток javascript (это означает, что если вам нужна кнопка входа в личный стиль)

Ответ 3

Попробуйте зарегистрировать первый вызов в некоторой локальной переменной и затем обработать его

Это быстрое решение помогает мне:

function login() {
  var initializedGoogleCallback = false
  gapi.auth.signIn({
    'callback': function (authResult) {
       if (!initializedGoogleCallback) {
         // after first call other will be ignored
         initializedGoogleCallback = true;
         if (authResult['status']['signed_in']) {
           console.log('Okay');
         } else {
           console.log('Error');
         }
       }
    }
  });
}

также вы можете добавить следующий код перед вызовом gapi.auth.signIn

window.removeEventListener('load')

Ответ 4

Это намеренный план настройки уровня страницы! Он присутствует на странице, что вызывает обратный вызов при завершении загрузки Javascript. То, что вы должны сделать, это подготовиться к этому в вашем коде.

Не показывайте кнопку входа в систему до тех пор, пока вы не получите обратный вызов - если authResult['status']['signed_in'] == true, тогда обработайте пользователя как подписанный (настройте сеанс и т.д., что бы вы обычно не делали). Если он неверен, тогда отобразите кнопку.

function signinCallback(authResult) {
  if (authResult['status']['signed_in']) {
    document.getElementById('signinButton').setAttribute('style', 'display: none');
    // Do sign in stuff here!
  } else {
    document.getElementById('signinButton').setAttribute('style', 'display: block');
  }
}

Я бы не стал использовать силу утверждения утверждения, если вы можете!

Ответ 5

Как и ответ Дрю Тейлора, чтобы избежать двойного обратного вызова с помощью чистого знака в JavaScript, вы можете проверить состояние сеанса пользователя:

if (authResult["status"]["method"] == "PROMPT") {...}

Я думаю, что обратный вызов с помощью метода AUTO запускается нижней панелью приветствия, которая появляется при первом входе в систему.

Ответ 6

наконец, я решил с обходным путем; я не знаю, правильно ли это подход или я просто обманываю, но я делаю так:

в первую очередь некоторые script на странице (я использую bootstrap + jquery)

function render() {
    //I am not using it but kept anyway

 }
var i;
// Function called from a onClick on a link or button (the 'sign in with g+' button)
function gp_login() {
    i=0;
    $('#alertbox').remove();
    var additionalParams = {
     'callback': signinCallback,
     /*'approvalprompt': 'force' finally removed*/
    };
    $('#gp-login').button('loading');
    gapi.auth.signIn(additionalParams); 
}

function signinCallback(authResult) { //my callback function
        var email='';
        var given_name='';
        if (authResult['status']['signed_in']) { //get some user info
            gapi.client.load('oauth2', 'v2', function() {
                gapi.client.oauth2.userinfo.get().execute(function(resp){
                    email = resp.email; //get user email
                    given_name = resp.given_name; //get user email
                    family_name=resp.family_name;
                    id=resp.id;
                    if (i<2) { //execute the doLogin just one time (my cheat)
                        doLogin(email,given_name,family_name,id); //dologin does my logic with an ajax call to signup/register user to my site
                    }
                    i=2;
                });
            });
        } else {
        // Update the app to reflect a signed out user
      }

}

этот аспект имеет часть doLogin, вызванную всего один раз, но обратный вызов вызывается дважды (gapi.client.oauth2.userinfo.get() эта функция вызывается дважды); с немного большей настройкой с проверкой if/var, я думаю, что можно позвонить все раз. Таким образом, если пользователь уже предоставил auth, он будет автоматически подписан.

Я замечаю, что иногда у google есть всплывающий слой в нижней части слоя, показывающий "приветственное сообщение назад", но я не понимал, когда он появляется, или если я должен называть его вручную