使用ui-router和AngularFire

时间:2017-07-11 16:16:17

标签: angularjs firebase angular-ui-router firebase-authentication

我在我的应用中使用Google Firebase进行身份验证。我一直在关注他们的文档https://www.firebase.com/docs/web/libraries/angular/guide/user-auth.html。虽然此方法使用stateChange,但据我所知,ui-router已弃用此方法。所以在网上看我从这个例子中改变了我的脚本:

app.run(["$rootScope", "$state", function($rootScope, $state) {

    $rootScope.$on("$stateChangeError", 
       function(event, toState, toParams, fromState, fromParams, error) {
            console.log('HELLO')
            if (error === "AUTH_REQUIRED") {
                $state.go("login");
        }
    });
}]);

为:

app.run(($transitions, $state) => {
    $transitions.onError({}, ($transition$) => {
        if ($transition$.$to().name !== 'init' && $transition$.$from().name !== 'error') {
            $state.go("login");
        }
    });
});

我正在尝试处理错误,因此当用户尝试访问需要身份验证的页面时,它会将它们引导回登录屏幕。第二种方法是工作,当它试图将状态更改为login时冻结它。

问题

为什么我的脚本在尝试访问需要身份验证的网页时无法将用户重定向到login页面?

app.config(['$stateProvider', function($stateProvider, ) {

    $stateProvider
    .state('login', {
        url: '/login',
        component: 'login'
    })
    .state('patents', {
        url: '/patents',
        component: 'patents',
        resolve: {
            currentAuth: function(authentication) {
                return authentication.requireAuth();
            }
     });
}]);


app.factory('authentication', ['$rootScope', '$location', '$firebaseAuth', '$firebaseObject', function($rootScope, $location, $firebaseAuth, $firebaseObject) {

var auth = $firebaseAuth();

//LOAD OF OTHER AUTHENTICATION METHODS

    return {

        requireAuth: function() {
            return auth.$requireSignIn();
        }
    }
}])      

1 个答案:

答案 0 :(得分:1)

我有一个类似的用例。我没时间真正弄清楚你的具体问题的答案,但我可以为你的情况提供解决方案。

让我们在转换开始之前处理身份验证。

app.run(["$state", '$transitions', '$q', 'Auth',
    function($state, $transitions, $q, Auth) {

  //overrides default error outputting by ui.router
  $state.defaultErrorHandler(function(error) {
    console.error(error);
  });

  //redirects to login page if we're not signed in
  $transitions.onBefore({to: 'home.**', from: '**'}, function(trans) {
    var deferred = $q.defer();

    Auth.$requireSignIn().then(function() {
      //we're signed in, so proceed to home.**
      deferred.resolve();
    }).catch(function() {
      //we're not signed in and home.** requires authentication
      //so resolve with the state you want to reroute to, refreshing
      //the url w/ reload === true
      var params = { reload: true };
      deferred.resolve($state.target('login', undefined, params));
    });

    return deferred.promise;
  });

  //redirects to home page if we're signed in
  $transitions.onBefore({to: 'login.**', from: '**'}, function(trans) {
    var deferred = $q.defer();

    Auth.$requireSignIn().then(function() {
      //we're signed in, so lets avoid going to login, and instead
      //go to our authenticated state
      var params = { reload: true };
      deferred.resolve($state.target('home', undefined, params));
    }).catch(function() {
      //we're not signed in, so continue to login.**
      deferred.resolve(); 
    });

    return deferred.promise;
  });
}]);

Config看起来像这样:

$stateProvider
.state('login', {
  url: '/login'
  // + some template/controller/resolve...
})
.state('home', {
  url: '/home'
  // + some template/controller/resolve...
})

继续认可工厂

app.factory("Auth", ["$firebaseAuth", function($firebaseAuth) {
  return $firebaseAuth();
}]);

可以找到onBefore的文档here