本文介绍了角验证:应避免对不同的路线多决心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发一个应用角度。在此,我才去的仪表板验证用户。要做到这一点我已经写了签到功能

I'm developing an Angular application. In this, I'm authenticating the user before going to dashboard. To achieve this I have wrote the signIn function as

登录的功能

this.signIn = function(credentials) {
        console.info('AccountController[signIn] Called');

        AuthService
            .login(credentials)
            .then(function(authenticatedUser) {
                $scope.globals['currentUser'] = authenticatedUser;

                AuthService.setCurrentUser(authenticatedUser);

                $scope.globals['isAuthenticated'] = true;
                $location.path('/dashboard');                    

            }).catch(function(error) {
                console.warn('AccountController[signIn] :: ', error);
                Flash.Error(error);
                $scope.credentials.password = '';
            });
    };

我也想访问的路线,如果他们没有登录,限制用户。为了实现这个目标,我想出了这个脏code

路线

$stateProvider
        .state('signIn', {
            url: '/signIn',
            templateUrl: 'partials/signIn/signIn.html',
            data: {
                pageTitle: 'SignIn'
            },
            controller: 'AccountController',
            controllerAs: 'ac',
            resolve: {
                auth: ['$q', 'AuthService', function($q, AuthService) {
                    var userInfo = AuthService.isAuthenticated();
                    console.info('SignIn Route[isAuthenticated] :: ', userInfo);
                    if (!userInfo) {
                        return $q.when(userInfo);
                    } else {
                        return $q.reject({
                            isAuthenticated: true
                        });
                    }
                }]
            }
        })
        .state('dashboard', {
            url: '/dashboard',
            templateUrl: 'partials/dashboard.html',
            controller: 'DashboardController',
            access: {
                requiredLogin: true
            },
            resolve: {
                auth: ['$q', 'AuthService', function($q, AuthService) {
                    var authenticated = AuthService.isAuthenticated();
                    console.info('dashboard Route[isAuthenticated] :: ', authenticated);
                    if (authenticated) {
                        return $q.when(authenticated);
                    } else {
                        return $q.reject({
                            isAuthenticated: false
                        });
                    }
                }]
            }
        })
        .state('manageStudent', {
            url: '/manageStudent',
            templateUrl: 'partials/manageStudent.html',
            access: {
                requiredLogin: true
            },
            resolve: {
                auth: ['$q', 'AuthService', function($q, AuthService) {
                    var authenticated = AuthService.isAuthenticated();
                    if (authenticated) {
                        return $q.when(authenticated);
                    } else {
                        return $q.reject({
                            isAuthenticated: false
                        });
                    }
                }]
            }
        });


App.run(['$rootScope', 'settings', '$state', 'AuthService', '$location', function($rootScope, settings, $state, AuthService, $location) {
    $rootScope.$state = $state; // state to be accessed from view
    $rootScope.$settings = settings; // state to be accessed from view

    $rootScope.$on('$stateChangeStart', function(event, next,nextParams,prev,prevParams) {

        // If the user is logged in don't allow him to land on the Login Page


        if (next.access !== undefined) {
            if (next.access.requiredLogin && !AuthService.isAuthenticated()) {

                $location.path('/signIn');
            }
        }


    });


    $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {

        event.preventDefault();
        if (!error.isAuthenticated) {
            console.warn("I'm not Authenticated.Going to Sign-in");

            return $location.path('/signIn');
        } else {
            console.info("I'm Authenticated");
            $location.path('/dashboard');

        }
    });
}]);

我之所以说上面的code DIRTY 是因为,如果我有10路,我想未通过身份验证的用户保护,我在所有路由,以复制出同样的决心功能。

Reason I said the above code DIRTY is because, If I have 10 routes which I want to protect from Unauthenticated user, I have to copy the same resolve function in all the routes.

所以我的问题是,我应该怎么做才能摆脱多重化解功能,并能够编写DRY code?

So my question is , what should I do to get rid of multiple resolve function and being able to write DRY code?

推荐答案

由于 AUTH 应在每条路线的改变来解决,这是不够的,只是把它包装成单独的工厂(这是一个单,将只运行一次)。为了克服这个限制,它应该是一个函数

Since auth should be resolved on each route change, it is insufficient to just wrap it into separate factory (which is a singleton and will run only once). To get round this limitation it should be a function

app.factory('authResolver', function ($q, AuthService) {
  return function () {
    // ...
  };
});

这在每个航线运行的决心。

which runs on every route resolve

...
resolve: {
  auth: function (authResolver) {
    return authResolver();
  }
}

不过不是干的,但是这是推荐的湿度水平。

Still not that DRY, but that's the recommended humidity level.

更激进的做法,可能会挽救样板之一决心,节省code几行会出现类似的:

More radical approach that may save the one from boilerplate resolve and save a few lines of code will be similar to that:

app.run(function ($rootScope, authResolver) {
  $rootScope.$on('$stateChangeStart', function (e, to) {
    if (to.doAuthPlease)
      to.resolve.auth = authResolver();
  });
});

...
doAuthPlease: true,
resolve: {}

与ngRoute中提到的答案明显的区别是,在UI路由器,你需要有定义的解析对象要能新解析器动态添加的状态。它可以治疗或阔叶原样。

The obvious difference with ngRoute in the mentioned answer is that in UI Router you need to have resolve object defined to be able to add new resolvers to the state dynamically. It can be treated like that or leaved as is.

这篇关于角验证:应避免对不同的路线多决心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 17:53