41

我正在将 Google+ 登录与我的网站集成,这也允许用户使用 Twitter 和 Facebook 登录。因此,该网站的登录页面有 3 个按钮,每个服务一个。

我遇到的问题是在以下情况下:

  • 用户进入登录页面
  • 用户使用 G+ 成功登录
  • 用户退出我的网站(但该帐户仍与 G+ 关联,退出该网站不会断开 G+ 帐户)
  • 用户再次访问登录页面
  • 在此阶段,“使用 G+ 登录”按钮会呈现并自动将用户登录到与 G+ 关联的帐户,而无需用户单击该按钮

问题是,在重新访问登录页面时,我希望用户可以选择使用其他服务登录,而不是自动使用 G+ 登录。如果用户想使用 G+ 登录,他们可以通过单击按钮来实现 - 然后用户将自动登录。

是否可以防止在按钮渲染时自动登录?我可以通过在按钮上使用 as 属性来模拟它data-approvalprompt="force",但我认为这不是一个理想的解决方案(然后用户必须通过确认过程,我希望避免这种情况)

4

10 回答 10

35

更新

防止自动登录的最佳支持方法是使用 API 方法,该方法gapi.auth2.getAuthInstance().signOut()将在您的站点被调用后阻止自动登录。 演示在这里

在演示中,用户在离开页面时退出,如以下代码所示:

window.onbeforeunload = function(e){
  gapi.auth2.getAuthInstance().signOut();
};

现在,无论何时用户退出站点(例如关闭窗口、导航离开),他们都会被注销,并且登录按钮不会触发登录,直到用户单击它。

我不建议您在自己的实现中执行此操作,而是允许用户在他们不再希望登录时明确退出。另外,请注意我的示例是一个演示,您可能不想签名用户离开您的网站时会自动退出。

原帖

首先,您不应该使用 data-approvalprompt="force" ,因为这会导致向您的应用程序/客户端发出额外的授权子令牌,并且设计用于在凭据丢失后需要重新授权用户的场景服务器-边。

其次,您可能不希望出现用户需要点击登录的行为,因为他们已经“登录”到他们的 Google 帐户,并且需要再次登录(或触发登录)可能会造成混淆,分别为您的网站。

如果您真的想这样做,您将为登录按钮执行显式渲染,但不会按照Google+ 登录文档中的说明调用 gapi.signin.render,直到您知道用户不会自动获得登录。

以下代码显示了如何启用登录按钮的显式呈现:

<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
{"parsetags": "explicit"}
</script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<head>
<script type="text/javascript">
var token = "";
function onSigninCallbackVanilla(authResponse){
   // in a typical flow, you show disconnect here and hide the sign-in button
}

以下代码向您展示了如何显式呈现按钮:

  <span id="signinButton">
    <button id = "shim" onclick="gapi.signin.go(); $('#shim').hide();">Show the button</button>
    <span
      class="g-signin"
      data-callback="onSigninCallbackVanilla"
      data-clientid="YOUR_CLIENT_ID"
      data-cookiepolicy="single_host_origin"
      data-requestvisibleactions="http://schemas.google.com/AddActivity"
      data-scope="https://www.googleapis.com/auth/plus.login">

    </span>
  </span>  

您如何传达用户已退出您的站点可能会因站点而异,但一种方法可能是设置一个 cookie,指示用户的“已退出”状态,然后将其用作触发器用于阻止显式加载。当用户访问您的网站并禁用 cookie 或使用单独的登录浏览器时,该行为会变得有点棘手。为了解决这个问题,您可以做一些复杂的事情,例如在登录回调中通过 XHR 从您的服务器查询用户状态,并假装不知道用户已登录 Google+。

于 2013-03-19T15:12:37.903 回答
26

只需在回调函数中检查 g-auth-window :

    function google_sign_callback(authResult){
        if(authResult['g-oauth-window']){

        }else if(authResult['error']) {

        }
    }
于 2013-04-12T21:12:32.397 回答
14

我遇到了这个问题并使用了 auth2.disconnect()

function onSignIn(googleUser) {
    var profile = googleUser.getBasicProfile();
    var auth2 = gapi.auth2.getAuthInstance();
    auth2.disconnect();

    //do other stuff
}

编辑:您需要在断开连接之前存储令牌,因为在某些情况下,断开连接后 id_token 将变为空:

function onSignIn(googleUser) {
    var profile = googleUser.getBasicProfile();
    var idToken=profile.id_token;
    googleUser.disconnect()

    //use idToken for server side verification
}

如果我是正确的,你有你自己的网站登录机制,只需要谷歌登录就可以在经过验证的电子邮件上注册用户。在这种情况下,您可以在获得个人资料信息后轻松断开连接。下次加载页面时,您将看到“登录”按钮而不是“登录”按钮。

于 2017-11-11T07:18:23.933 回答
3

不幸的是gapi.auth.signOut(),当我请求用户数据时,调用使应用程序再次登录(它都不是持久的)

因此,@class 建议的解决方案是撤销令牌:

  $.ajax({
    type: 'GET',
    url: 'https://accounts.google.com/o/oauth2/revoke?token=' +
        gapi.auth.getToken().access_token,
    async: false,
    contentType: 'application/json',
    dataType: 'jsonp',
    success: function(result) {
      console.log('revoke response: ' + result);
      $('#authOps').hide();
      $('#profile').empty();
      $('#visiblePeople').empty();
      $('#authResult').empty();
      $('#gConnect').show();
    },
    error: function(e) {
      console.log(e);
    }
  });
于 2014-04-14T15:25:53.073 回答
3

我正在使用https://developers.google.com/identity/sign-in/web/build-button为我的网络应用程序构建登录按钮,让用户可以选择通过 Facebook 或 Google 登录。这段代码很容易获得 Id_token。但是,如果用户已经登录,它也会自动登录用户。

因此,在脚本开头添加以下代码片段有助于我控制注册过程。

    window.onbeforeunload = function(e){
      gapi.auth2.getAuthInstance().signOut();
    };

谢谢!

于 2017-01-01T21:52:29.593 回答
3

我也有同样的问题,我是如何修复它的。我可能不确定这是一种更标准的方法,但它仍然适用于我......

从谷歌开发者添加这个谷歌 JS

<script src="https://apis.google.com/js/platform.js" async defer></script>
<script>

function onSuccessG(googleUser) {
        var profile = googleUser.getBasicProfile();
        console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
        console.log('Name: ' + profile.getName());
        console.log('Image URL: ' + profile.getImageUrl());
        console.log('Email: ' + profile.getEmail());
}
function onFailureG(error) {
    console.log(error);
}
function renderGmail() {

  gapi.signin2.render('my-signin2', {
    'scope': 'https://www.googleapis.com/auth/plus.login',
    'width': 0,
    'height': 0,
    'longtitle': true,
    'theme': 'dark',
    'onsuccess': onSuccessG,
    'onfailure': onFailureG
  });
}

现在添加 html 链接并 onClick 调用此 renderGmail() 函数。

<a href="javascript:void(0)" onclick="renderGmail();"> SignUp with Gmail</a>

我希望这有效...

于 2015-10-20T11:13:52.930 回答
2

我们的 AngularJS 解决方案是:

$scope.$on('event:google-plus-signin-success', function (event, authResult) {
                if( authResult.status.method !== "AUTO"){
                    onGoogleLogIn(authResult[settings.configKeys.googleResponseToken]);
                }
            });
于 2014-12-19T00:14:51.737 回答
1

当您开始将 Google 登录和 OAuth 访问令牌用于其他 Google 服务时,接受的答案不再有效。当用户退出时,访问令牌立即过期。相反,我会推荐这个 SO post的答案,其中涉及将点击事件处理程序附加到 Google 登录按钮。只有当用户单击登录按钮并成功登录到他们的 Google 帐户后,回调事件才会触发。

于 2020-03-27T00:30:43.333 回答
1

我已经为此苦苦挣扎了一段时间,找不到使用登录的“简单实现”来阻止自动登录 Google 的方法

我最终使用了不尝试自动登录的自定义集成(也允许我同时更改外观)

于 2017-01-26T19:34:24.090 回答
0

我通过向我的 Google 登录按钮添加点击处理程序解决了这个问题。点击处理程序将全局 Javascript 变量设置google_sign_intrue. 当onSuccess()处理程序触发时(无论是在页面加载时自动触发,还是在用户单击登录按钮时手动触发),它首先检查是否google_sign_in== true,然后才继续让用户登录:

<div id="google-signin2" onclick="return do_click_google_signin();"></div>

<script>
    var google_sign_in = false; // assume

    function do_click_google_signin() {
        google_sign_in = true;
    }

    function onSuccess( googleUser ) {
        if ( google_sign_in ) {
            // Process sign-in
        }
    }

    // Other redundant login stuff not shown...
</script>
于 2018-08-06T21:26:46.487 回答