如何在页面刷新后退出用户?

时间:2016-01-31 19:34:40

标签: javascript angularjs google-signin

我正在关注Google's guide以退出用户。

考虑到刷新页面后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();
    });
}

但我在else块中得到uncaught exception: This method can only be invoked after the token manager is started

我也尝试将auth实例存储在本地存储中,但这样做会导致一些循环对象值错误,同时对其进行字符串化。

一个可行的解决方案是做一个

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

但是,除了执行不需要的重定向之外,不会仅仅记录我的应用程序用户,这会影响他所记录的所有Google服务。

有不同的方法吗?

2 个答案:

答案 0 :(得分:7)

有一种更简单的方法,你只需要在调用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();
   });
});

答案 1 :(得分:5)

我不得不在我的登录页面控制器中检索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>

解决了退出问题。但是,如果登录页面已刷新,则其控制器逻辑将在定义gapi.auth2之前执行,并且将点击处理程序成功附加到登录按钮是不可行的。

为了避免这种情况 - 尽管不是一个优雅的解决方案 - 我使用$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);

编辑:另一种可能的解决方案是使用承诺回调让控制器逻辑等到承诺得到解决,即直到Google API完全加载并且gapi.auth2可以使用。 通过这样做可以实现这一目标:

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

然后在控制器中:

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

但是,这种方法的缺点是它比使用$interval的第一个更慢(连接点击处理程序的时间是两倍)。