如何使用Angular UI-Router重定向未经验证的电子邮件用户?

时间:2015-02-28 13:32:58

标签: angularjs meteor angular-ui-router

我将AngularJS与Meteor一起使用,并希望将未经验证的电子邮件用户重定向到登录页面。我在/client/routes.js

中创建了一个符号视图
app.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider){
  $urlRouterProvider.otherwise('/');

  $stateProvider

  .state('signin', {
    url:'/signin',
    views: {
      main: {
        templateUrl: 'client/views/profile/signin.tpl'
      }
    }
  })

请注意,为了简洁起见,我还没有列出其他州。

现在,如果用户的电子邮件尚未经过验证,我想将用户重定向到此登录页面。如何修改UI-Router FAQs下面的示例以满足我的需求?其他不使用以下示例的解决方案对我来说是可以接受的,只要它们解决了手头的问题。

  

示例:使用state config上的数据对象来定义规则   将对用户运行逻辑的函数(这里使用一个例子   服务名为$ currentUser)。 $ stateChangeStart处理程序捕获   所有状态转换并在允许之前执行此规则检查   转换,可能阻止它和/或重定向到不同的   状态。

app.config(function($stateProvider) {
  $stateProvider.state('privatePage', {
    data: {
      rule: function(user) {
        // ...
      }
  });
});
app.run(function($rootScope, $state, $currentUser) {
  $rootScope.$on('$stateChangeStart', function(e, to) {
    if (!angular.isFunction(to.data.rule)) return;
    var result = to.data.rule($currentUser);

    if (result && result.to) {
      e.preventDefault();
      // Optionally set option.notify to false if you don't want 
      // to retrigger another $stateChangeStart event
      $state.go(result.to, result.params, {notify: false});
    }
  });
});

2 个答案:

答案 0 :(得分:1)

FAQ中的示例尝试创建向任何页面添加规则的一般方法。让我们保持简单:

app.run(function($rootScope, $state, UserService) {
    $rootScope.$on('$stateChangeStart', function(event, toState) {
        // don't check auth on login routes
        if (["signin"].indexOf(toState.name) === -1) {
            if (UserService.doesNotHaveVerifiedEmail()) {
                event.preventDefault();
                $state.go('signin');
                return;
            }
        }
    }
}); 

无论何时加载状态并且它不是 signin 状态,您检查用户是否已经过验证(取决于您的应用程序,这里我注入了一个UserService,我认为该用户服务已知道用户的状态如果没有,则阻止该状态更改并将其重定向到登录页面。

答案 1 :(得分:1)

您可以使用angular-ui-router提供的resolve功能在状态解决之前检查当前用户的电子邮件验证。以下是代码的外观:

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

        var isVerified = ['User', '$state', '$q',
            function(User, $state, $q) {
                var d = $q.defer();
                var loginPromise = User.getVerificationStatus();
                loginPromise.then(
                    function(response) {
                        d.resolve(response);
                    },
                    function(error) {
                        $state.go('login');
                    });
                return d.promise;
            }
        ];

        $urlRouterProvider.otherwise('/');

        $stateProvider

            .state('signin', {
                url: '/signin',
                views: {
                    main: {
                        templateUrl: 'client/views/profile/signin.tpl'
                    }
                }
            })
            .state('home', {
                url: '/home',
                views: {
                    main: {
                        templateUrl: 'client/views/profile/home.tpl'
                    }
                },
                resolve: {
                    verified: isVerified
                }
            });
    }
]);

此处home状态会在解析之前检查验证。我已经注入了一个服务User,它将安排用户是否经过验证的信息。

您可以将resolve属性仅添加到要检查验证状态的状态。通过这种方式,这比检查$stateChangeStart事件更好,无论是否需要检查,每次状态发生时都会触发该事件。

以下是documentation的链接。