Google+登录JavaScript回调问题

Google+ Sign-In with JavaScript callback issue

本文关键字:问题 回调 JavaScript 登录 Google+      更新时间:2024-05-21

我正在开发一个功能,允许用户使用他们的谷歌帐户登录我的网站。

我的代码基于Google文档(其他signIn()选项在元标记中)。

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

当我调用login()时,谷歌弹出窗口,我批准了我的应用程序的条款,一切都很好。

但回调被调用了两次:

  • 第一种情况:如果我从未批准过应用程序权限,那么在弹出窗口打开时会调用回调,并且我将在何时批准权限。所以它会写"错误"answers"好"
  • 第二种情况:如果我已经批准了权限,它会写两次"OK"

我在signIn()函数中添加了选项'approvalprompt': 'force'。回调函数不再被调用两次,但它会强制用户批准应用程序的权限,即使之前已经批准。所以它对用户不友好。

有没有一种友好的用户方式可以一次批准应用程序的权限,而不需要两次回调?

谢谢。

我在这里也面临同样的问题,但我通过按钮点击处理程序调用了gap.auth.signIn()。回调仍被调用两次。我在两个authResult对象之间注意到的一件事是,authResult.status.method在第一次调用中(在弹出窗口出现之前)是"AUTO",在由于先前的授权而自动关闭窗口之后的第二次调用中是"PROMPT"。

我现在正在探索的解决方案是忽略AUTO实例,只处理回调的PROMPT实例。由于文档中缺乏"状态"对象的详细信息,不确定一旦我在谷歌内撤销权限,这将如何工作。

我面临着同样的问题:在用户已经授予权限的情况下,signin回调调用了两次;本地变量方法(initializedGoogleCallback)对我不起作用,因为它只在用户已经授予访问权限时调用回调一次,但如果用户是新用户,则不会调用它。经过一点研究(我特别使用g+auth在网站上挖掘),我注意到他们都使用'approvalprompt': 'force',并且他们每次都有已经授权的用户重新评估"离线访问"策略。甚至是我在设置应用程序时遵循的谷歌示例(https://developers.google.com/+/web/signin/javascript流),即使它没有提到它,它也使用"force"参数。目前,如果你想使用javascript流(也就是说,如果你需要一个个人风格的签名按钮),这似乎是唯一的解决方案

尝试在某个局部变量中注册第一个调用,然后对其进行处理

这个快速解决方案对我有帮助:

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

您也可以在调用中的gap.auth.sign之前添加以下代码

window.removeEventListener('load')

与Drew Taylor的答案一样,为了避免使用纯javascript登录解决方案进行双重回调,您可以检查用户的会话状态:

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

我认为AUTO方法的回调是由第一次登录时出现的底部欢迎栏触发的。

这是页面级配置的有意计划!它出现在页面中会导致在Javascript加载完成时触发回调。您应该做的是在代码中为此做好准备。

在收到回调之前不要显示登录按钮——如果是authResult['status']['signed_in'] == true,则将用户视为已登录(设置会话等,无论您通常会做什么)。如果为false,则显示该按钮。

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

如果可以的话,我会避免使用审批提示强制!

我终于用一个变通方法解决了问题;我不知道这是正确的方法,还是我只是作弊,但我是这样做的:

首先,页面中的一些脚本(我使用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部分一次,但回调调用两次(gap.client.oauth2.userinfo.get()此函数调用两次);通过对if/var检查进行更多的调整,我认为可以一次调用所有内容。这样,如果用户已经授予了身份验证,则会自动对其进行签名。

我注意到,有时谷歌在层的底部有一个弹出层,显示"欢迎回来的消息",但我不明白它是什么时候出现的,或者我是否必须手动调用它