12

我有一个基本的 PHP 应用程序,其中用户登录存储在 HTTP 会话中。该应用程序有一个主模板,比如 index.html,它使用 ngView 切换子视图,如下所示

<body ng-controller='MainCtrl'>
    <div ng-view></div>
</body>

现在,这个主模板可以通过基本的 PHP 控件进行保护,但我有子模板(即用户列表、添加用户、编辑用户等),它们是纯 html 文件,根据我的路由设置从角度包含。

虽然我能够检查与 http 服务请求有关的身份验证,但一位用户能够导航到子模板 url 并访问它。我怎样才能防止这种情况发生?

4

2 回答 2

14

我会创建这样的服务:

app.factory('routeAuths', [ function() {
  // any path that starts with /template1 will be restricted
  var routeAuths = [{
      path : '/template1.*',
      access : 'restricted'
  }];
  return {
    get : function(path) {
      //you can expand the matching algorithm for wildcards etc.
      var routeAuth;
      for ( var i = 0; i < routeAuths.length; i += 1) {
        routeAuth = routeAuths[i];
        var routeAuthRegex = new RegExp(routeAuth.path);
        if (routeAuthRegex.test(path)) {
          if (routeAuth.access === 'restricted') {
            return {
              access : 'restricted',
              path : path
            };
          }
        }
      }
      // you can also make the default 'restricted' and check only for 'allowed'
      return {
        access : 'allowed',
        path : path
      };
    }
  };
} ]);

并在主/根控制器中监听$locationChangeStart事件:

app.controller('AppController', ['$scope', '$route', '$routeParams', '$location', 'routeAuths',
  function(scope, route, routeParams, location, routeAuths) {
    scope.route = route;
    scope.routeParams = routeParams;
    scope.location = location;

    scope.routeAuth = {
    };

    scope.$on('$locationChangeStart', function(event, newVal, oldVal) {
      var routeAuth = routeAuths.get(location.path());
      if (routeAuth.access === 'restricted') {
        if (scope.routeAuth.allowed) {
          event.preventDefault();
        }
        else {
          //if the browser navigates with a direct url that is restricted
          //redirect to a default
          location.url('/main');
        }
        scope.routeAuth.restricted = routeAuth;
      }
      else {
        scope.routeAuth.allowed = routeAuth;
        scope.routeAuth.restricted = undefined;
      }
    });

}]);

演示

参考资料

更新

为了完全防止 html 模板访问,最好也在服务器上完成。因为如果您从服务器上的静态文件夹提供 html,用户可以直接访问该文件,例如:root_url/templates/template1.html,从而绕过角度检查器。

于 2012-12-17T17:17:48.537 回答
0

如果您想阻止他们访问该页面,请创建一个服务:http ://docs.angularjs.org/guide/dev_guide.services.creating_services

此服务可以由您向 routeParams 注册的所有控制器注入依赖项。

在该服务中,您可以拥有一个功能,该功能将检查该人是否已登录,然后使用http://docs.angularjs.org/api/重新路由他们(可能返回登录页面?) ng .$location#path。在每个控制器中调用此函数,如下所示:

function myController(myServiceChecker){
    myServiceChecker.makeSureLoggedIn();
}

makeSureLoggedIn 函数将检查他们所在的当前 url(使用 $location.path),如果不是允许的,则将它们重定向回允许的页面。

我很想知道是否有办法阻止 routeParams 甚至触发,但至少这会让你做你想做的事。

编辑:还可以在这里查看我的答案,您甚至可以阻止他们访问该页面:

AngularJS - 检测、停止和取消路由更改

于 2012-12-17T15:59:25.423 回答