谷歌登录 - 在刷新
问题描述:
登出后,我有以下设置:谷歌登录 - 在刷新
.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。
任何人都可以看到一个问题,为什么它会返回false?还有什么我需要做的,以确保谷歌记得我吗?
答
你的主要问题似乎是,你通过调用googleService.load()
gapi.auth2.init()
一遍又一遍。
我的建议是存储重新使用的初始化承诺,而不是多次创建它。
您还需要添加一个条件来处理过期的访问令牌。
.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
和getProfile
)现在返回一个承诺,只有解决一旦auth2
API然而这个初始化永远只发生一次了。
例如
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();
}
});
}];
答
您需要在您的cloud
控制器中包含authenticated
作为依赖项。此外,在你在你的成功处理程序googleService
应该defer.resolve()
后你你做localStorage['access_token'] = p.access_token;
和$rootScope.profile = p.profile;
答
嗨执行以下更改代码,让我知道,如果它的工作原理。
.service('googleService', ['$q', function ($q) {
var self = this;
this.load = function(){
gapi.load('auth2', callback);
};
function callback(){
var deferred = $q.defer();
gapi.auth2.init()//use your client credentials here
.then(function(){ deferred.resolve(); });
return deferred.promise;
}
self.isSignedIn=function (auth2){
return auth2.isSignedIn.get();
};
self.signOut =function(auth2){
var deferred = $q.defer();
auth2.signOut().then(deferred.resolve, deferred.reject);
return deferred.promise;
};
self.getProfile= function(auth2) {
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(){
googleService.isSignedIn(gapi.auth2.getAuthInstance()).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(){
googleService.getProfile(gapi.auth2.getAuthInstance()).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) {
}]);
你可以提供一个小提琴? –
也许我错过了一些东西,但我没有看到你曾经访问过本地存储令牌'localStorage.getItem('access_token')'。您需要检查该令牌是否存在,以及它是否仍然有效,以便您在刷新时进行身份验证。此外,您可能需要考虑使用cookie,因为cookie会提供一个可以不断重置的超时时间。请参阅:http://*.com/questions/244882/what-is-the-best-way-to-implement-remember-me-for-a-website –
我在认证的“解决方案”中访问它,但我可以做错了@ td-edge – bryan