谷歌登录 - 在刷新

问题描述:

登出后,我有以下设置:谷歌登录 - 在刷新

.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?还有什么我需要做的,以确保谷歌记得我吗?

+2

你可以提供一个小提琴? –

+1

也许我错过了一些东西,但我没有看到你曾经访问过本地存储令牌'localStorage.getItem('access_token')'。您需要检查该令牌是否存在,以及它是否仍然有效,以便您在刷新时进行身份验证。此外,您可能需要考虑使用cookie,因为cookie会提供一个可以不断重置的超时时间。请参阅:http://*.com/questions/244882/what-is-the-best-way-to-implement-remember-me-for-a-website –

+0

我在认证的“解决方案”中访问它,但我可以做错了@ td-edge – bryan

你的主要问题似乎是,你通过调用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 }; 
      } 
     }); 
    }; 

}]) 

您的每个服务的方法(isSignedInsignOutgetProfile)现在返回一个承诺,只有解决一旦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(); 
     } 
    }); 
}]; 
+0

干净的解决方案! – Kalyan

+0

这也是真的 –

+0

谢谢菲尔,乍一看这似乎很好用!谢谢你的解释 – bryan

您需要在您的cloud控制器中包含authenticated作为依赖项。此外,在你在你的成功处理程序googleService应该defer.resolve()你你做localStorage['access_token'] = p.access_token;$rootScope.profile = p.profile;

+0

很确定所有的解析器都被解析*无论它们是否包含在控制器参数中。 – Phil

+0

这不适用于角色I的工作版本,1.3.x. –

+0

你会在这里看到它确实是真的〜http://plnkr.co/edit/Y4N6ropCXTjEHvJQ13Au?p=preview – Phil

嗨执行以下更改代码,让我知道,如果它的工作原理。

.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) { 

    }]); 
+1

不解决使用auth实例的承诺,它会创建无限循环的promise解决方案(愚蠢的Google API) – Phil

+0

感谢您指出它。我已更新我的代码 – Kalyan

+0

没问题。我在那个上浪费了太多时间。 – Phil