简体   繁体   English

如何在页面刷新后注销用户?

[英]How to sign out a user after page refresh?

I'm following Google's guide to sign out a user. 我正在关注Google的指南以退出用户。

Considering that gapi.auth2 will be undefined after refreshing the page, I'm doing: 考虑到刷新页面后未定义gapi.auth2 ,我正在做:

if (gapi.auth2) {
    var auth2 = gapi.auth2.getAuthInstance();
    auth2.signOut();
} else {
    gapi.load('auth2', function () {
        gapi.auth2.init({
            client_id: 'myAppID',
            cookiepolicy: 'single_host_origin'
        }).signOut();
    });
}

But I get uncaught exception: This method can only be invoked after the token manager is started in the else block. 但是我得到了uncaught exception: This method can only be invoked after the token manager is started在else块中uncaught exception: This method can only be invoked after the token manager is started

I also have tried to store the auth instance in local storage but doing that led to some cyclic object value errors while stringifying it. 我也尝试将auth实例存储在本地存储中,但这样做会导致一些循环对象值错误,同时对其进行字符串化。

One posible solution is to do a 一个可行的解决方案是做一个

document.location.href = "https://www.google.com/accounts/Logout?continue=https://appengine.google.com/_ah/logout?continue=myUrl";

but, instead of logging the user out only of my application, that would affect all Google's services in which he is logged, besides doing an unwanted redirection. 但是,除了执行不需要的重定向之外,不会仅仅记录我的应用程序用户,这会影响他所记录的所有Google服务。

Is there a different approach? 有不同的方法吗?

there is a easier way, you just have to call .then after calling gapi.auth2.init 有一个更简单的方法,你只需要在调用gapi.auth2.init后调用.then

gapi.load('auth2', function () {
   var auth2 = gapi.auth2.init({
       client_id: 'myAppID',
       cookiepolicy: 'single_host_origin'
   });
   auth2.then(function(){
        // this get called right after token manager is started
        auth2.signOut();
   });
});

Instead of retrieving the singleton for the GoogleAuth library and setting up the client in my sign-in page controller, I had to initialize it in the index.html file: 我不得不在我的登录页面控制器中检索GoogleAuth库的单例并设置客户端,而是必须在index.html文件中初始化它:

<script src="https://apis.google.com/js/api:client.js?onload=start" async defer></script>
<script>
    function start() {
      gapi.load('auth2', function() {
        auth2 = gapi.auth2.init({
            client_id: 'myAppID',
            cookiepolicy: 'single_host_origin'
        });
      });
    }
</script>

That solved the logout problem. 这解决了注销问题。 However, if the sign-in page was refreshed, its controller logic would be executed before the gapi.auth2 was defined and it wouldn't be posible to successfully attach the click handler to the sign-in button. 但是,如果登录页面被刷新,其控制器逻辑将在定义gapi.auth2之前执行,并且将点击处理程序成功附加到登录按钮是gapi.auth2

In order to avoid that - though not being an elegant solution -, I used $interval to wait until gapi.auth2 was initialized: 为了避免这种情况 - 尽管不是一个优雅的解决方案 - 我使用$ interval来等待gapi.auth2初始化:

waitForAuth2Initialization = $interval(function () {
    console.log("Checking...");
    if (!gapi.auth2)
        return;
    console.log("Ok, gapi.auth2 is not undefined anymore");
    var auth2 = gapi.auth2.getAuthInstance();
    // Attach signin
    auth2.attachClickHandler...

    $interval.cancel(waitForAuth2Initialization);
}, 50);

EDIT: another possible solution is to use a promise callback for the controller logic to wait until the promise is resolved ie until Google API is fully loaded and gapi.auth2 is ready to use. 编辑:另一种可能的解决方案是使用promise回调让控制器逻辑等到promise被解决,即直到Google API完全加载并且gapi.auth2可以使用。 It is posible to achieve that by doing: 通过以下方式实现这一目标是可行的:

<script src="https://apis.google.com/js/api:client.js?onload=start" async defer></script>
<script>
    gapiPromise = (function () {
        var deferred = $.Deferred();
        window.start = function () {
            deferred.resolve(gapi);
        };
        return deferred.promise();
    }());
    auth2Promise = gapiPromise.then(function () {
        var deferred = $.Deferred();
        gapi.load('auth2', function () {
            auth2 = gapi.auth2.init({
                client_id: 'myAppID',
                cookiepolicy: 'single_host_origin'
            }).then(function () { 
                deferred.resolve(gapi.auth2); 
            });
        });
        return deferred.promise();
    });
</script>

And then in the controller: 然后在控制器中:

auth2Promise.then(function () {
    console.log("Ok, gapi.auth2 is not undefined anymore");
    var auth2 = gapi.auth2.getAuthInstance();
    // Attach signin
    auth2.attachClickHandler...
});

But, the downside of this approach is that it is slower (taking twice as much time for the click handler to be attached) than the first one using $interval . 但是,这种方法的缺点是它比使用$interval的第一个方法更慢(连接点击处理程序的时间是两倍)。

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

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