AngularJS - prevent not authenticated user from accessing given routes

前端 未结 2 522
梦毁少年i
梦毁少年i 2021-01-13 10:01

In my app when user is logged in I have authService which sets internal flag isAuthenticated. Now on every route change I have listener attached to

相关标签:
2条回答
  • 2021-01-13 10:44

    To prevent a user for accessing routes you have to do several things:

    First, set your routes and add a property like 'access' : allowAnonymous : true or false

    // in app.js
    var myApp = angular.module('myApp',['ngResource', 'ngCookies', 'ngRoute']);       
    myApp.config(function ($httpProvider, $routeProvider) {
       window.routes = {
            '/Login':
               { templateUrl: '/Account/Login',
                 controller: 'AccountController',
                 access : {allowAnonymous : true}
               },
            '/MembersPage':
               { templateUrl: '/Home/SomePage,
                 controller: SomePageController',
                 access: {allowAnonymous:false}
               }
             };
    
            for (var path in window.routes) {
               $routeProvider.when(path, window.routes[path]);
        }
        $routeProvider.otherwise({ redirectTo: '/Login' });
    });   
    

    Second, you must recognize an authenticated user:

    There are several ways for doing that but I prefer using the power of AngularJS throughout the use of ‘Services’. Therefore, I have created a ‘UserService’ where we store the current user name and a value-indicating if is authenticated or not.

    // in UserService.js
    myApp.factory('userService', function () {
    var user = {
        isLogged: false,
        username: '',       
    };
    
    var reset = function() {
        user.isLogged = false;
        user.username = '';
    };
    
    return {
        user: user,
        reset : reset
      };
    });
    

    Last thing, capture route changes events and treat them correspondingly:

    After we have the service in place, it is time to use it and implement the check functionality for a route. There are several methods that intercept the route change event, but we are interested only in those that occur before the user was redirected so we can check if is authenticated: ‘$routeChangeStart’, ‘$locationChangeStart’. Here we can check if the route that the user is going to allows anonymous access and if the user is logged in. If the case of failure, we can display an error message and redirect the user to the login page.

    // in RootController.js
    myApp.controller('RootController',
    function ($scope, $route, $routeParams, $location, $rootScope, authenticationService,   
    userService, toaster) {
     $scope.user = userService.user;
     $scope.$on('$routeChangeStart', function (e, next, current) {               
         if (next.access != undefined && !next.access.allowAnonymous && !$scope.user.isLogged) {
                    $location.path("/Login");                   
                }
            });
    
            $scope.logout = function () {
                authenticationService.logout()
                    .success(function (response) {
                        userService.reset();                       
                        toaster.pop("info", 'You are logged out.', '');
                    });
            };
    
     $rootScope.$on("$locationChangeStart", function (event, next, current) {
      for (var i in window.routes) {
        if (next.indexOf(i) != -1) {
         if (!window.routes[i].access.allowAnonymous && !userService.user.isLogged) {
              toaster.pop("error", 'You are not logged in!', '');
                 $location.path("/Login");                                                 
                        }
                    }
                }
            });
        });
    

    Complete article is here: http://net-daylight.blogspot.ro/

    Hope it helps!

    0 讨论(0)
  • 2021-01-13 10:47

    I'd do something like this in the top level controller, which would be the first controller that's called when the page is refreshed (apologize for typos in the js, I'm a coffeescript guy):

    var authCheck = function (event, next, current) {
        if(isRouteRestricted(next)) {
            authService.currentUser().then(null, function() {
                $location.path('/login');
            });
        }
    }
    
    authCheck(null, populateNextSomehow).then(function () {
        // all of your controller code, probably in a separate function
    });
    
    $rootScope.$on("$routeChangeStart", authCheck);
    

    This will ensure that the controller code cannot be called until the authCheck is complete.

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