How to hide templates with AngularJS ngView for unauthorized users?

后端 未结 2 1194
面向向阳花
面向向阳花 2021-02-04 11:06

I have a basic PHP app, where the user login is stored in the HTTP Session. The app has one main template, say index.html, that switch sub-view using ngView, like this



        
相关标签:
2条回答
  • 2021-02-04 11:09

    If you want to block them from going to that page create a service: http://docs.angularjs.org/guide/dev_guide.services.creating_services

    This service can be dependency injected by all your controllers that you registered with the routeParams.

    In the service you can would have a function that would check to see if the person is logged in or not and then re-route them (back to the login page perhaps?) using http://docs.angularjs.org/api/ng.$location#path. Call this function in each of the controllers like so:

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

    The makeSureLoggedIn function would check what current url they're at (using the $location.path) and if it's not one they're allowed to, redirect them back to a page that they are allowed to be.

    I'd be interested to know if there's a way to prevent the routeParams from even firing, but at least this will let you do what you want.

    Edit: Also see my answer here, you can prevent them from even going to the page:

    AngularJS - Detecting, stalling, and cancelling route changes

    0 讨论(0)
  • 2021-02-04 11:15

    I would create a service like this:

    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
          };
        }
      };
    } ]);
    

    And in the main/root controller listen for $locationChangeStart events:

    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;
          }
        });
    
    }]);
    

    Demo:

    • plunker

    References:

    • angularjs services
    • location

    UPDATE:

    In order to fully prevent html template access then it's best done on the server as well. Since if you serve the html from a static folder on server a user can access the file directly ex: root_url/templates/template1.html thus circumventing the angular checker.

    0 讨论(0)
提交回复
热议问题