我有以下设置:
.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',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',function ($rootScope,$scope,$q,$state,googleService) { $scope.options = { 'onsuccess': function(response) { $state.go('cloud'); } } }]) .controller('cloud','$timeout','$http','$httpParamSerializerJQLike',$timeout,$http,$httpParamSerializerJQLike) { }]);
基本上发生的是,当我使用google登录按钮登录时,它会登录,并且googleService.getProfile()表示我已登录.
但是,如果我刷新页面,googleService.isSignedIn()返回false.
任何人都可以看到为什么会返回错误的问题?还有什么我需要做的,以确保谷歌记得我吗?
解决方法
您的主要问题似乎是您通过googleService.load()一遍又一遍地调用了gapi.auth2.init().
我的建议是存储重新使用的初始化承诺,而不是创建许多次.
您还需要添加一个条件来处理过期的访问令牌.
.service('googleService',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和getProfile)现在都返回一个承诺,只有在auth2 API被初始化后才能解析,然而这只是一次.
例如
var authenticated = ['$q','$window',$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(); } }); }];