简体   繁体   English

使用 Google+ 登录时阻止自动登录

[英]Preventing automatic sign-in when using Google+ Sign-In

I am in the process of integrating Google+ sign in with my site, which also lets users sign in with Twitter and Facebook.我正在将 Google+ 登录与我的网站集成,这也允许用户使用 Twitter 和 Facebook 登录。 The sign in page of the site therefore has 3 buttons, one for each of the services.因此,站点的登录页面有 3 个按钮,每个服务一个。

The issue I am having is in the following scenario:我遇到的问题是在以下场景中:

  • user goes to the sign in page用户转到登录页面
  • user signs in successfully with G+用户使用 G+ 成功登录
  • user signs out of my site (but the account is still associated with G+, signing out of the site does not disconnect the G+ account)用户退出我的网站(但该帐户仍与 G+ 相关联,退出网站不会断开 G+ 帐户的连接)
  • user visits the sign in page again用户再次访问登录页面
  • at this stage the Sign in with G+ button is rendered and automatically signs the user into the account associated with G+ without the user having to click the button在此阶段,“使用 G+ 登录”按钮呈现并自动将用户登录到与 G+ 关联的帐户,而无需用户单击该按钮

The problem is that on revisiting the sign in page, I want the user to have the option of signing in with another service, rather than automatically being signed in with G+.问题是,在重新访问登录页面时,我希望用户可以选择使用其他服务登录,而不是自动使用 G+ 登录。 If the user wants to sign in with G+ then they can do so by clicking the button - the user will then be signed in automatically.如果用户想使用 G+ 登录,那么他们可以通过单击按钮来实现 - 用户将自动登录。

Is it possible to prevent this automatic sign in on button render?是否可以在按钮渲染时阻止这种自动登录? I can simulate it by using the data-approvalprompt="force" as an attribute on the button, but I don't think this is an ideal solution (the user then has to go through the confirmation process, which I would ideally would like to prevent)我可以通过使用data-approvalprompt="force"作为按钮上的属性来模拟它,但我认为这不是一个理想的解决方案(然后用户必须通过确认过程,我希望阻止)

Update更新

The best supported way to prevent automatic sign-in is to use the API method gapi.auth2.getAuthInstance().signOut() which will prevent automatic sign-in on your site after it has been called.阻止自动登录的最佳支持方法是使用 API 方法gapi.auth2.getAuthInstance().signOut() ,这将阻止在您的站点被调用后自动登录。 Demo here .演示在这里

In the demo, the user is signed out when they leave the page as shown in the following code:在演示中,用户在离开页面时注销,如以下代码所示:

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

Now, whenever the user exits the site (eg closes the window, navigates away), they will be signed out and the sign in button will not trigger sign-in until the user clicks it.现在,无论何时用户退出站点(例如关闭窗口、导航离开),他们都将被注销并且登录按钮不会触发登录,直到用户单击它。

I don't recommend you do this in your own implementation but instead allow the user to explicitly sign out when they no longer desire want to be signed in. Also, please note that my example is a demo, you probably do not want to sign the user out automatically any time they leave your site.我不建议您在自己的实现中执行此操作,而是允许用户在他们不再希望登录时明确退出。另外,请注意我的示例是一个演示,您可能不想登录用户在离开您的网站时自动退出。

Original Post原帖

First, you should not be using data-approvalprompt="force" as this will cause extra authorized subtokens to be issued to your application / client and is designed to be used in scenarios where the user needs to be reauthorized after credentials have been lost server-side.首先,您不应该使用 data-approvalprompt="force",因为这会导致向您的应用程序/客户端发出额外的授权子令牌,并且旨在用于在凭据丢失后用户需要重新授权的场景服务器-边。

Second, you probably do not want to have the behavior where the user needs to click to sign in because they are already "signed in" to their Google account and it could be confusing to need to sign in (or trigger sign-in) again, separately, for your site.其次,您可能不希望出现用户需要点击登录的行为,因为他们已经“登录”了他们的 Google 帐户,并且需要再次登录(或触发登录)可能会造成混淆,分别用于您的网站。

If you really wanted to do this, you would perform an explicit render for the signin button but would not make the call to gapi.signin.render as documented in the Google+ sign-in documentation until you are aware that the user will not automatically get signed in.如果您真的想这样做,您将对登录按钮执行显式渲染,但不会按照Google+ 登录文档中的说明调用 gapi.signin.render,直到您意识到用户不会自动获取已登录。

The following code shows how to enable explicit render of the sign-in button:以下代码显示了如何启用登录按钮的显式呈现:

<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
}

The following code shows you how to explicitly render the 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>  

How you're communicating that the user is signed out of your site is probably going to vary from site to site, but one approach could be to set a cookie indicating the "signed out" state for a user and then using this as the trigger for blocking explicit load.您如何传达用户已退出您的网站可能会因站点而异,但一种方法可能是设置一个 cookie,指示用户的“已退出”状态,然后将其用作触发器用于阻止显式加载。 The behavior gets a little trickier when a user visits your site and has disabled cookies or uses a separate, signed-in, browser.当用户访问您的网站并禁用 cookie 或使用单独的登录浏览器时,这种行为会变得有点棘手。 To address this, you could do something complicated like querying the user state from your server over XHR on the sign-in callback and pretending not to know the user is signed in to Google+.为了解决这个问题,您可以做一些复杂的事情,例如在登录回调中通过 XHR 从您的服务器查询用户状态,并假装不知道用户已登录到 Google+。

Just check for g-auth-window in the callback function:只需在回调函数中检查 g-auth-window :

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

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

        }
    }

I had this issue and used auth2.disconnect()我遇到了这个问题并使用了auth2.disconnect()

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

    //do other stuff
}

Edit: you need to store the token before you disconnect because in some cases id_token will become null after disconnect:编辑:您需要在断开连接之前存储令牌,因为在某些情况下,断开连接后 id_token 将变为空:

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

    //use idToken for server side verification
}

If i'm correct you have your own sign in mechanism for your site and just need google sign in to sign up a user on verified email.如果我是正确的,您有自己的网站登录机制,只需要谷歌登录即可在经过验证的电子邮件上注册用户。 in this case you can easily disconnect after you get the profile info.在这种情况下,您可以在获取配置文件信息后轻松断开连接。 Next time you load the page you will see "sign in" button instead of "signed in " button.下次加载页面时,您将看到“登录”按钮而不是“登录”按钮。

Unfortunately calling gapi.auth.signOut() made the app to log-in again when I'm requesting user data (neither it is persistent)不幸的是,当我请求用户数据时,调用gapi.auth.signOut()使应用程序再次登录(都不是持久的)

So the solution, as suggested by @class is to revoke the token:因此,@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);
    }
  });

I too has same issue this how i fixed it.I may not sure this is a stander way to do it but still it works fine with me...我也有同样的问题,我是如何修复它的。我可能不确定这是一种标准的方法,但它仍然适用于我......

add this Google JS from google developer从谷歌开发人员添加这个谷歌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
  });
}

Now add html link and onClick call this renderGmail() function.现在添加 html 链接和 onClick 调用这个 renderGmail() 函数。

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

I hope this works...我希望这有效...

I am usinghttps://developers.google.com/identity/sign-in/web/build-button to build the sign in button for my web app which gives the user a choice to log in through either Facebook or Google.我正在使用https://developers.google.com/identity/sign-in/web/build-button为我的网络应用程序构建登录按钮,让用户可以选择通过 Facebook 或 Google 登录。 This code is pretty easy for obtaining the Id_token.这段代码很容易获取Id_token。 However it also came with automatic signing in of the user if the user is already signed in.但是,如果用户已经登录,它也会自动登录用户。

Thus, adding the following snippet in the beginning of the script helped me control the signup procedure.因此,在脚本开头添加以下代码片段有助于我控制注册过程。

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

Thanks!谢谢!

Our AngularJS solution was:我们的 AngularJS 解决方案是:

$scope.$on('event:google-plus-signin-success', function (event, authResult) {
                if( authResult.status.method !== "AUTO"){
                    onGoogleLogIn(authResult[settings.configKeys.googleResponseToken]);
                }
            });

I have been struggling with this for a while and could not find a way to prevent automatic sign in to Google using the "easy implementation" of the Sign-in我已经为此苦苦挣扎了一段时间,但找不到一种方法来防止使用登录的“轻松实现”自动登录 Google

I ended up using thecustom integration which does not attempt to auto sign in (also allowed me to change the appearance in the same time)我最终使用了不尝试自动登录的自定义集成(也允许我同时更改外观)

The accepted answer no longer works when you start to use both Google Sign In and OAuth access tokens for other Google services.当您开始将 Google 登录和 OAuth 访问令牌用于其他 Google 服务时,接受的答案不再有效。 The access tokens expire immediately when the user is signed out.当用户退出时,访问令牌立即过期。 Instead, I would recommend the answer from this SO post , which involves attaching a click event handler to the Google sign in button.相反,我会推荐这篇 SO post 中的答案,其中包括将点击事件处理程序附加到 Google 登录按钮。 Only once the user clicks the sign in button and successfully logs into their Google account will the callbacks events fire.只有当用户点击登录按钮并成功登录他们的 Google 帐户后,回调事件才会触发。

I solved this by adding a click handler to my Google sign-in button.我通过向我的 Google 登录按钮添加一个点击处理程序来解决这个问题。 The click handler sets a global Javascript variable google_sign_in to true .点击处理程序将全局 Javascript 变量google_sign_intrue When the onSuccess() handler fires (whether automatically on page load, or manually when the user clicks the sign-in button), it first checks whether google_sign_in == true and only then does it continue signing the user in:onSuccess()处理程序触发时(无论是在页面加载时自动触发,还是在用户单击登录按钮时手动触发),它首先检查google_sign_in == true是否为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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM