我正在开发一项功能,允许用户使用他们的Google帐户登录我的网站。
我的代码基于Google documentation(其他signIn()选项位于元标记中)。
function login() {
gapi.auth.signIn({'callback':
function (authResult) {
if (authResult['status']['signed_in']) {
console.log('Okay');
}else {
console.log('Error');
}
}
});
}
当我调用login()时,会出现Google弹出窗口,我批准了我的应用程序条款,一切正常。
但回调被调用两次:
我在signIn()函数中添加了选项'approvalprompt': 'force'
。回调函数不再被调用两次,但它会强制用户批准应用程序的权限,即使之前已批准。所以它不是用户友好的。
是否有一种友好的用户方式来批准应用程序的权限一次而没有两次回调?
谢谢。
答案 0 :(得分:8)
我在这里遇到同样的问题,但我通过按钮点击处理程序调用gapi.auth.signIn()。回调仍然被调用两次。我注意到两个authResult对象之间的一件事是authResult.status.method在第一次调用中是'AUTO'(在弹出窗口出现之前)并且在窗口被自动关闭之后在第二次调用中是'PROMPT'授权。
我现在正在探索的解决方案是忽略AUTO实例并仅处理回调的PROMPT实例。由于“状态”对象上的文档中缺少详细信息,因此在我撤销Google中的权限后,我不确定这是如何工作的。
答案 1 :(得分:6)
我遇到了同样的问题:如果用户已经授予权限,则签名回调两次;局部变量方法(initializedGoogleCallback)对我不起作用,因为它仅在用户已经授予访问权限时调用回调一次,但如果用户是新用户则不调用它。
经过一些研究(我特别是使用g + auth在网站上挖掘)后,我注意到他们都使用'approvalprompt': 'force'
并且他们已经授权用户每次都重新批准“离线访问”策略。
即使我按照设置我的应用程序(https://developers.google.com/+/web/signin/javascript-flow)的谷歌示例,即使它没有提到它,它也使用“force”参数。
目前它似乎是唯一的解决方案,如果你想使用javascript流(这意味着如果你需要一个个人风格的登录按钮)
答案 2 :(得分:4)
尝试在某个局部变量中注册第一个调用,然后处理它
这个快速的解决方案可以帮助我:
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')
答案 3 :(得分:1)
这是页面级配置的有意计划!它存在于页面中导致回调在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');
}
}
如果可以,我会避免使用批准提示力!
答案 4 :(得分:1)
就像Drew Taylor的回答一样,为了避免使用纯javascript登录解决方案进行双重回调,您可以check the user's session state:
if (authResult["status"]["method"] == "PROMPT") {...}
我认为使用AUTO方法的回调是由首次登录时出现的底部欢迎栏触发的。
答案 5 :(得分:0)
最后我解决了一个解决方法;我不知道这是否是正确的接近方式,或者我只是作弊,但我这样做:
首先是页面中的一些脚本(我正在使用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
}
}
这个approch只有一次调用doLogin部分,但回调被调用两次(gapi.client.oauth2.userinfo.get()这个函数被调用两次);使用if / var检查进行更多调整我认为可以调用一次。 这样,如果用户已经授予了auth,它将自动签名。
我注意到有时谷歌在图层底部有一个弹出图层,显示“欢迎回复消息”,但我不明白何时出现或者我必须手动调用