【问题标题】:How to restrict routes with $routeProvider如何使用 $routeProvider 限制路由
【发布时间】:2015-12-10 07:58:15
【问题描述】:

在 MEAN 应用程序中,我有一个带有 Auth 工厂的 authService 模块,其中包含 authFactory.isLoggedIn 函数:

// check if a user is logged in
    // checks if there is a local token
    authFactory.isLoggedIn = function() {
        if (AuthToken.getToken()) 
            return true;
        else
            return false;   
    };

所以我想我可以将它与 $routeProvider 的 resolve 属性一起使用,如下所示:

var MyModule = angular.module('app.routes', ['ngRoute']);

MyModule.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {


    $routeProvider

        // route for the home page
        .when('/', {
            templateUrl : 'app/views/pages/home.html'
        })

        // login page
        .when('/login', {
            templateUrl : 'app/views/pages/login.html',
            controller  : 'mainController',
                controllerAs: 'login'
        })

        // register page
        .when('/register', {
            templateUrl: 'app/views/pages/register.html',
            controller: 'userCreateController',
            controllerAs: 'register'
        })

        // upload page
        .when('/upload', {
            templateUrl : 'app/views/pages/upload.html',
            controller: 'uploadController',
            controllerAs: 'userupload',
            resolve: function($q, $location) {
                var deferred = $q.defer();
                deferred.resolve();
                if (!Auth.isLoggedIn) {
                    $location.path('/login');
                }
                return deferred.promise;
            }

        })

        //logout
        .otherwise({redirectTo: '/'});

    $locationProvider.html5Mode(true);

}]);

很遗憾,这无法阻止未经身份验证的用户访问上传页面,而且我没有看到任何错误报告。 我已经看到了执行此操作的更简单方法的实例,例如:

.when('/upload', {
            templateUrl : 'app/views/pages/upload.html',
            controller: 'uploadController',
            controllerAs: 'userupload',
            isLoggedIn: true

        })

但这也不起作用,这很遗憾,因为它要简单得多。

【问题讨论】:

    标签: angularjs mean-stack


    【解决方案1】:

    最后我决定使用 $routeProvider 的 resolve 属性,所以在尝试了 http://midgetontoes.com/blog/2014/08/31/angularjs-check-user-login 上的解决方案之后 我想出了:

    var MyModule = angular.module('app.routes', ['ngRoute']);
    
    MyModule.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
    
        var onlyLoggedIn = function($location, $q, Auth) {
            var deferred = $q.defer();
            if (Auth.isLoggedIn()) {
                deferred.resolve();
            } else {
                deferred.reject();
                $location.url('/login');
            }
            return deferred.promise;
        };
    
    
        $routeProvider
    
            // route for the home page
            .when('/', {
                templateUrl : 'app/views/pages/home.html'
            })
    
            // login page
            .when('/login', {
                templateUrl : 'app/views/pages/login.html',
                controller  : 'mainController',
                    controllerAs: 'login'
            })
    
            // register page
            .when('/register', {
                templateUrl: 'app/views/pages/register.html',
                controller: 'userCreateController',
                controllerAs: 'register'
            })
    
            // upload page
            .when('/upload', {
                templateUrl : 'app/views/pages/upload.html',
                controller: 'uploadController',
                controllerAs: 'userupload',
                resolve:{loggedIn:onlyLoggedIn}
    
    
            })
    
            //logout
            .otherwise({redirectTo: '/'});
    
        $locationProvider.html5Mode(true);
    
    }]);
    

    我确信这不如@Dimitiri Algazin 提出的自定义http拦截器或@Pasan Ratnayake的解决方案那么简单,但它确实满足了我使用resolve的要求。无论如何感谢@Dimitri 和@Pasan。

    【讨论】:

      【解决方案2】:

      您可以通过多种方式实现此功能。

      最简单的方法是将类似于以下代码的检查添加到您不希望用户访问的每个控制器。

      // You could re-direct the user to a '401' state as well
      if (!authFactory.isLoggedIn())
        $state.go('login');
      

      【讨论】:

        【解决方案3】:

        添加自定义 http 拦截器。这不是确切的代码,只是算法,可能缺少一些语法:

        .factory('myHttpInterceptor', function($q, $location, AuthToken) {
        
            function isLoggedIn() {
                return !!AuthToken.getToken();
            }
        
            function canRecover(response) {
                var status = response.status;
                var config = response.config;
                var method = config.method;
                var url = config.url;
        
                console.log("--->>> ", method, status, url);
        
                if (status == 401) {
                    alert("401");
                } else if ( status == 403) {
                    alert("403");
                } else if (status == 404) {
                    alert("404");
                } else if (status == 405) {
                    alert("405");
                } else if (status == 500) {
                    alert("500");
                } else {
                }
                return response;
            }
        
            return {
                // optional method
                'request': function(config) {
                    if (isLoggedIn()) {
                        return config;
                    } else {
                        $location.path('login');
                    }
                },
        
                // optional method
                'response': function(response) {
                // do something on success
                return response;
                },
        
                // optional method
                'requestError': function(rejection) {
                    return $q.reject(canRecover(rejection));
                },
        
                // optional method
                'responseError': function(rejection) {
                    return $q.reject(canRecover(rejection));
                }
            };
        })
        .config(['$httpProvider', function($httpProvider) {
            $httpProvider.interceptors.push('myHttpInterceptor');
        }])
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-01-27
          • 2019-10-24
          • 1970-01-01
          • 2016-03-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-05
          相关资源
          最近更新 更多