【问题标题】:How to sign out a user after page refresh?页面刷新后如何注销用户?
【发布时间】:2016-05-09 04:33:36
【问题描述】:

我正在关注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 服务,而不是仅将用户从我的应用程序中注销。

有不同的方法吗?

【问题讨论】:

标签: javascript angularjs google-signin


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我不必为 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 的第一个方法慢(附加点击处理程序花费的时间是第一个的两倍)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-04
      • 1970-01-01
      • 1970-01-01
      • 2020-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多