Secure routing using AngularJS
- 2020-06-15 07:49:32
- OfStack
Introduction to the
AngularJS has been in use for a long time since its inception. It is an javascript framework for developing single-page applications (SPA). It has some nice features, such as two-way binding, instructions, etc. This article focuses on the Angular routing security policy. It is a client-side security framework that can be implemented with Angular development. I have tested it. In addition to securing client-side routing, you also need to secure server-side access. Client-side security policies help reduce additional access to the server. However, if someone is spoofing the browser to access the server, the server-side security policy should be able to deny unauthorized access. In this article, I will only discuss client-side security policies.
Define global variables at the application module level
Define roles for applications:
var roles = {
superUser: 0,
admin: 1,
user: 2
};
Define unauthorized access routes for applications:
var routeForUnauthorizedAccess = '/SomeAngularRouteForUnauthorizedAccess';
Define authorization services
appModule.factory('authorizationService', function ($resource, $q, $rootScope, $location) {
return {
// Cache permissions to Session To avoid subsequent requests to the server
permissionModel: { permission: {}, isPermissionLoaded: false },
permissionCheck: function (roleCollection) {
// return 1 A promise (promise).
var deferred = $q.defer();
// This is saved only in the scope of the commitment 1 A pointer to the upper scope.
var parentPointer = this;
// Check whether the permission object has been obtained from the service ( A list of roles for the logged in user )
if (this.permissionModel.isPermissionLoaded) {
// Checks whether the current user has permission to access the current route
this.getPermission(this.permissionModel, roleCollection, deferred);
} else {
// If we don't have permission objects yet, we'll go to the server and get them.
// 'api/permissionService' In this example web Service address.
$resource('/api/permissionService').get().$promise.then(function (response) {
// When the server returns, we start populating the permission object
parentPointer.permissionModel.permission = response;
// Sets the mark for completion of permission object processing to true And stored in a Session .
// Session The permissions object can be reused in subsequent routing requests
parentPointer.permissionModel.isPermissionLoaded = true;
// Checks whether the current user has a mandatory role to access the route
parentPointer.getPermission(parentPointer.permissionModel, roleCollection, deferred);
}
);
}
return deferred.promise;
},
// methods : Checks whether the current user has a mandatory role to access the route
//'permissionModel' The role information of the current user returned from the server is saved
//'roleCollection' A list of roles that have access to the current route is saved
//'deferred' Is the object used to process the promise
getPermission: function (permissionModel, roleCollection, deferred) {
var ifPermissionPassed = false;
angular.forEach(roleCollection, function (role) {
switch (role) {
case roles.superUser:
if (permissionModel.permission.isSuperUser) {
ifPermissionPassed = true;
}
break;
case roles.admin:
if (permissionModel.permission.isAdministrator) {
ifPermissionPassed = true;
}
break;
case roles.user:
if (permissionModel.permission.isUser) {
ifPermissionPassed = true;
}
break;
default:
ifPermissionPassed = false;
}
});
if (!ifPermissionPassed) {
// If the user does not have the necessary permissions, we direct the user to a page where he does not have access
$location.path(routeForUnauthorizedAccess);
// Since there is a delay in this process, during which time the page position may change,
// We will be 1 Direct monitoring $locationChangeSuccess The event
// And when the event occurs, the promise is resolved.
$rootScope.$on('$locationChangeSuccess', function (next, current) {
deferred.resolve();
});
} else {
deferred.resolve();
}
}
};
});
3 Encrypted routing
Then let's use our efforts to encrypt the route:
var appModule = angular.module("appModule", ['ngRoute', 'ngResource'])
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/superUserSpecificRoute', {
templateUrl: '/templates/superUser.html', // The routing view/template The path
caseInsensitiveMatch: true,
controller: 'superUserController', // The routing angular The controller
resolve: {
// Here we will use our efforts above to invoke the authorization service
// resolve is angular In the 1 A great feature to make sure
// Only after the commitments mentioned below have been processed
// Before the controller ( In this case, yes superUserController) Apply to routing.
permission: function (authorizationService, $route) {
return authorizationService.permissionCheck([roles.superUser]);
},
}
})
.when('/userSpecificRoute', {
templateUrl: '/templates/user.html',
caseInsensitiveMatch: true,
controller: 'userController',
resolve: {
permission: function (authorizationService, $route) {
return authorizationService.permissionCheck([roles.user]);
},
}
})
.when('/adminSpecificRoute', {
templateUrl: '/templates/admin.html',
caseInsensitiveMatch: true,
controller: 'adminController',
resolve: {
permission: function (authorizationService, $route) {
return authorizationService.permissionCheck([roles.admin]);
},
}
})
.when('/adminSuperUserSpecificRoute', {
templateUrl: '/templates/adminSuperUser.html',
caseInsensitiveMatch: true,
controller: 'adminSuperUserController',
resolve: {
permission: function (authorizationService, $route) {
return authorizationService.permissionCheck([roles.admin, roles.superUser]);
},
}
});
});