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