Google 登录 - 刷新时注销

2024-04-14

我进行了以下设置:

.service('googleService', ['$q', function ($q) {
    var self = this;

    this.load = function(){
        var deferred = $q.defer();
        gapi.load('auth2', function(){
            var auth2 = gapi.auth2.init();
            auth2.then(function(){ deferred.resolve(); });
            addAuth2Functions(auth2);
        });
        return deferred.promise;
    };

    function addAuth2Functions(auth2) {

        self.isSignedIn = function(){
            return auth2.isSignedIn.get();
        }

        self.signOut = function(){
            var deferred = $q.defer();
            auth2.signOut().then(deferred.resolve, deferred.reject);
            return deferred.promise;
        };

        self.getProfile = function() {
            if(auth2.isSignedIn.get()) return { signed_in: true, access_token: auth2.currentUser.get().Zi.id_token,profile: auth2.currentUser.get().getBasicProfile() };
            else return { signed_in: false };
        }

    }

}])

.config(function($stateProvider, $urlRouterProvider, $locationProvider) {

    $locationProvider.html5Mode(true);
    $urlRouterProvider.otherwise('/cloud');

    var guest = ['$q', '$rootScope', '$stateParams', 'googleService', function ($q, $rootScope, $stateParams, googleService) { 

        var deferred = $q.defer(); 

        googleService.load().then(function(){ 
            $q.when(googleService.isSignedIn()).then(function(r){ 
                if(r) deferred.reject(); 
                else deferred.resolve(); 
            }) 
        }); 

        return deferred.promise; 
    }];

    var authenticated = ['$q', '$rootScope', '$stateParams', 'googleService', function ($q, $rootScope, $stateParams, googleService) { 

        var deferred = $q.defer(); 

        googleService.load().then(function(){ 
            $q.when(googleService.getProfile()).then(function(p) { 
                if(p.signed_in) { 
                    deferred.resolve(); 
                    localStorage['access_token'] = p.access_token;
                    $rootScope.profile = p.profile; 
                } else deferred.reject(); 
            }) 
        }); 

        return deferred.promise; 
    }];

    $stateProvider

    .state('login', {
        url: '/',
        views: { 'main': { templateUrl: 'pages/templates/login.html', controller: 'login' } },
        resolve: { authenticated: guest }
    })

    .state('cloud', {
        url: '/cloud',
        views: { 'main': { templateUrl: 'pages/templates/cloud.html', controller: 'cloud' } },
        resolve: { authenticated: authenticated }
    })

})

.controller('login', ['$rootScope', '$scope', '$q', '$state', 'googleService', function ($rootScope, $scope, $q, $state, googleService) {
    $scope.options = { 'onsuccess': function(response) { $state.go('cloud'); } }
}])

.controller('cloud', ['$rootScope', '$scope', '$timeout', '$http', '$httpParamSerializerJQLike', function ($rootScope, $scope, $timeout, $http, $httpParamSerializerJQLike) { 

}]);

基本上发生的事情是,当我使用谷歌登录按钮登录时,它会登录并googleService.getProfile()说我已登录。

但是,如果我刷新页面,googleService.isSignedIn()返回假。

任何人都可以看到为什么它会返回 false 的问题吗?我还需要做些什么来确保谷歌记住我吗?


您的主要问题似乎是您正在打电话gapi.auth2.init()一遍又一遍地通过googleService.load().

我的建议是存储初始化承诺以供重复使用,而不是多次创建。

您还需要添加一个条件来处理过期的访问令牌。

.service('googleService', ['$q', function ($q) {
    const auth2InitPromise = $q(function(resolve) {
        gapi.load('auth2', function() {
            var auth2 = gapi.auth2.init();
            auth2.then(function() {
                resolve();
            });
        })
    });

    this.isSignedIn = function() {
        return auth2InitPromise.then(function() {
            return gapi.auth2.getAuthInstance().isSignedIn.get();
        });
    };

    this.signOut = function() {
        return auth2InitPromise.then(function() {
            const auth2 = gapi.auth2.getAuthInstance();
            return $q(function(resolve, reject) {
                auth2.signOut().then(resolve, reject);
            });
        });
    };

    this.getProfile = function() {
        return this.isSignedIn().then(function(isSignedIn) {
            if (isSignedIn) {
                const currentUser = gapi.auth2.getAuthInstance().currentUser.get();
                const authResponse = currentUser.getAuthResponse();
                return $q.when(authResponse.expires_at > Date.now() ? authResponse : currentUser.reloadAuthResponse()).then(function(ar) {
                    return {
                        signed_in: true,
                        access_token: ar.id_token,
                        profile: currentUser.getBasicProfile()
                    }                        
                });
            } else {
                return { signed_in: false };
            }
        });
    };

}])

您的每个服务的方法(isSignedIn, signOut and getProfile)现在返回一个承诺,只有在auth2API 已初始化,但是现在只发生一次。


例如

var authenticated = ['$q', '$rootScope', '$window', 'googleService', function ($q, $rootScope, $window, googleService) {
    return googleService.getProfile().then(function(p) {
        if (p.signed_in) {
            $window.localStorage.setItem('access_token', p.access_token);
            $rootScope.profile = p.profile;
            return true; // resolvers should always resolve with something   
        } else {
            return $q.reject();
        }
    });
}];
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Google 登录 - 刷新时注销 的相关文章

随机推荐

  • 如何保存单选按钮状态

    我正在开发Android应用程序 其中我打开自己的自定义对话框 当我选择单选按钮时 我使用单选按钮 毫无疑问它被选中并工作 但是当我再次打开对话框时 所有单选按钮都被取消选择 我想保存上一个按钮的状态 enter code here pri
  • Android AlertDialog 标题字体

    我正在尝试更改字体android support v7 app AlertDialog标题文本 方法一 TextView title TextView dialog findViewById android R id title retur
  • Redux 应用程序中每个减速器调用上深度复制状态有哪些缺点?

    进行深度复制是否有任何副作用state每次调用reducer函数时 在Redux应用程序中的appReducer上 我这么问是因为不可变的更新模式 https redux js org recipes structuring reducer
  • 区分鼠标和键盘触发onclick

    我需要找到一种方法来确定链接是否已通过鼠标单击或按键激活 a href Save a 这个想法是 如果他们使用鼠标点击链接 那么他们可以继续使用鼠标来选择下一步要做什么 但是 如果他们在页面上切换并切换到 保存 链接 那么我将打开下一行进行
  • 用于分类的 Python 向量化[重复]

    这个问题在这里已经有答案了 我目前正在尝试构建一个包含大约 80 个类别的文本分类模型 文档分类 当我使用随机森林构建和训练模型时 将文本矢量化为 TF IDF 矩阵后 该模型运行良好 然而 当我引入新数据时 我用来构建 RF 的相同单词不
  • 将 R 数据框中的多列转换为日期格式

    我有一个很大的数据文件 其中所有日期都已作为字符加载 我想将所有日期列更改为日期格式 大多数日期具有 y m d 格式 有些具有 Y m d 格式 有 25 列日期 因此单独更改每一列的效率很低 我可以 df DATE1 lt as Dat
  • Firebase:如何将虚 URL 添加到云函数?

    被简短提及here https stackoverflow com questions 45850375 use custom domain for google cloud function 但现在我已经将我的 GCP 项目连接到 Fir
  • 如何在“X”秒后调用 jquery 函数

    我有一个 jquery 函数 我需要在 Iframe 中打开网站后调用它 我正在尝试在 Iframe 中打开一个网络链接 打开它后我需要调用以下函数 那么我该怎么做呢 这是我的功能
  • xcode 4.5 崩溃日志符号除应用程序行外

    我怎样才能象征一切 这是一个例子 所以我正在谈论 Thread 0 name Dispatch queue com apple main thread Thread 0 Crashed 0 CoreFoundation 0x351642cc
  • 如何在标签中的 tkinter 上制作字幕?

    我有这个源代码 from Tkinter import import tkMessageBox import time class Window Tk def init self parent Tk init self parent sel
  • 将图像文件存储在 IndexedDB 中

    我在尝试将图像文件存储在 IndexedDB 中时遇到问题 我抓取文件对象并尝试将其推送到 IndexedDB 中 但它似乎抛出错误 DOM Exception DATA CLONE ERR 25 如何将如下所示的文件对象转换为可以存储在
  • 如何在Eclipse中添加JBoss服务器?

    我是 JBoss 的新手 刚刚安装了 Eclipse 我已将一个项目添加到工作区 现在我想将其部署到 Jboss 服务器 然而 在新的服务器运行环境列表中 JBoss 不可用 我正在使用以下 Eclipse 版本 面向 Web 开发人员的
  • 从 UIViewController 返回 NSString

    我想返回一个NSString 从一个名为InputUIViewController的UIViewController 到之前的一个名为CallerUIViewController的UIViewController 它启动了InputUIVi
  • F# 图表示例

    我想使用内置功能或免费库在 F 中做一些基本的图表 我会对一个非常基本的例子感到非常非常满意 如果可能的话 饼图 示例数据 John 34 Sara 30 Will 20 Maria 16 其中整数是饼图中要表示的百分比 我最近安装了 VS
  • 使用 D3 在地图上绘制点

    我正在尝试使用基于纬度和经度的 D3 地理库在地图上绘制一些点 但是 当我将这些值传递到投影函数时 它会导致坐标超出 SVG 图像的范围 我的代码基于文档中提供了这个示例 http bl ocks org mbostock 3757119
  • 为什么在 Angular 指令的链接函数中“this”为空?

    我正在尝试使用 TypeScript 和 Angular 编写动态模板 但由于某种原因 this 关键字始终为空 因此我无法访问我的私有成员 compile 有任何想法吗 非常感谢 指示 namespace ROD Features Pla
  • 使用带有函数和 mixins 的对象(而不是原型)是否会带来一些性能损失? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在 JavaScript 中执行 OOP 的一种常见方法是使用带有附加函数的对象 而不是使用内置的原型 构造函数和new操作员 Mixin 通常
  • 我的项目名称下出现错误,但不存在错误?

    基本上发生的事情是我的项目名称下出现一个错误 小红十字 就好像某个地方有错误一样 当我查看我的项目时 没有错误 当我运行我的代码时 没有错误 它工作得很好 有人可以向我解释一下如何修复它吗 这意味着什么 我正在使用 Eclipse Luna
  • Kubernetes - Pod 内的容器通信使用名称而不是“localhost”?

    来自 Kubernetesdocs http kubernetes io docs user guide pods Pod 中的应用程序都使用相同的网络命名空间 相同的 IP 和端口空间 因此可以 find 彼此并使用本地主机进行通信 是否
  • Google 登录 - 刷新时注销

    我进行了以下设置 service googleService q function q var self this this load function var deferred q defer gapi load auth2 functi