I have the following set up:
.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) {
}]);
Basically what is happening is, when I sign in using the google sign in button, it signs in and googleService.getProfile()
says that I am signed in.
However, if I refresh the page, googleService.isSignedIn()
returns false.
Can anyone see an issue in why it would be returning false? Is there something else I need to do to make sure google remembers me?
Your main problem appears to be that you're calling gapi.auth2.init()
over and over again via googleService.load()
.
My suggestion is to store the initialisation promises for re-use instead of creating it many times.
You'll also need to add a condition to handle an expired access token.
.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 };
}
});
};
}])
Each of your service's methods (isSignedIn
, signOut
and getProfile
) now return a promise that only resolves once the auth2
API is initialised however this only ever happens once now.
For example
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();
}
});
}];
You need to include authenticated
as a dependency in your cloud
controller. Also, in your googleService
in your success handler you should defer.resolve()
after you do localStorage['access_token'] = p.access_token;
and $rootScope.profile = p.profile;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With