Redirecting users based on role permissions

Loading

In an AngularJS application, users often have different roles (e.g., Admin, User, Guest) that determine which pages they can access. To enforce these permissions, we can use AngularJS routing ($routeProvider) along with $routeChangeStart to redirect users based on their roles.


1. Why Implement Role-Based Redirection?

Restrict unauthorized access to certain pages.
Enhance security by preventing direct URL access.
Improve user experience by guiding users to allowed pages.


2. Using $routeProvider to Define Role-Based Routes

First, define routes in app.config() and specify role-based access using resolve.

Example: Configuring Routes for Different Roles

var app = angular.module("myApp", ["ngRoute"]);

app.config(["$routeProvider", function($routeProvider) {
$routeProvider
.when("/", {
templateUrl: "home.html",
controller: "HomeController"
})
.when("/admin", {
templateUrl: "admin.html",
controller: "AdminController",
resolve: {
access: function(AuthService, $q, $location) {
var deferred = $q.defer();
if (AuthService.hasRole("admin")) {
deferred.resolve();
} else {
deferred.reject();
$location.path("/unauthorized");
}
return deferred.promise;
}
}
})
.when("/user", {
templateUrl: "user.html",
controller: "UserController",
resolve: {
access: function(AuthService, $q, $location) {
var deferred = $q.defer();
if (AuthService.hasRole("user")) {
deferred.resolve();
} else {
deferred.reject();
$location.path("/unauthorized");
}
return deferred.promise;
}
}
})
.when("/unauthorized", {
template: "<h2>Access Denied</h2><p>You do not have permission to access this page.</p>"
})
.otherwise({
redirectTo: "/"
});
}]);

How This Works:

  • The resolve function checks if the user has the required role.
  • If the user does not have permission, they are redirected to /unauthorized.

3. Creating the AuthService for Role-Based Access

Define a simple AuthService to store and verify user roles.

app.service("AuthService", function() {
var userRole = "guest"; // Default role (can be "admin" or "user")

this.setRole = function(role) {
userRole = role;
};

this.getRole = function() {
return userRole;
};

this.hasRole = function(role) {
return userRole === role;
};
});

How This Works:

  • setRole(role): Sets the user’s role dynamically.
  • getRole(): Retrieves the current user role.
  • hasRole(role): Checks if the user has the required role.

4. Redirect Users Globally with $routeChangeStart

For a centralized way to enforce role-based redirects, listen to route changes in app.run().

app.run(["$rootScope", "$location", "AuthService", function($rootScope, $location, AuthService) {
$rootScope.$on("$routeChangeStart", function(event, next) {
if (next.$$route && next.$$route.requiredRole) {
if (!AuthService.hasRole(next.$$route.requiredRole)) {
event.preventDefault(); // Stop navigation
$location.path("/unauthorized"); // Redirect to unauthorized page
}
}
});
}]);

How This Works:

  • Before navigating, AngularJS checks if the route has a requiredRole.
  • If the user lacks permission, it prevents navigation and redirects them.

5. Updating Routes to Use requiredRole Instead of resolve

Now, modify the $routeProvider routes:

app.config(["$routeProvider", function($routeProvider) {
$routeProvider
.when("/admin", {
templateUrl: "admin.html",
controller: "AdminController",
requiredRole: "admin"
})
.when("/user", {
templateUrl: "user.html",
controller: "UserController",
requiredRole: "user"
})
.when("/unauthorized", {
template: "<h2>Access Denied</h2><p>You do not have permission to access this page.</p>"
})
.otherwise({
redirectTo: "/"
});
}]);

How This Works:

  • Instead of using resolve, routes now include requiredRole.
  • $routeChangeStart handles redirection globally.

6. Allow Users to Switch Roles Dynamically

In the UI, allow role switching using buttons:

<button ng-click="setRole('admin')">Login as Admin</button>
<button ng-click="setRole('user')">Login as User</button>
<button ng-click="setRole('guest')">Logout</button>
<p>Current Role: {{ currentRole }}</p>

Modify the controller to update roles dynamically:

app.controller("RoleController", ["$scope", "AuthService", function($scope, AuthService) {
$scope.currentRole = AuthService.getRole();

$scope.setRole = function(role) {
AuthService.setRole(role);
$scope.currentRole = role;
};
}]);

Now users can switch roles dynamically!


7. Summary of Role-Based Redirection Approaches

ApproachProsCons
resolve in routes Blocks route before loading Needs duplication in each route
$routeChangeStart Centralized redirection Requires requiredRole in routes
Manual role checking in controllers Full control over logic More code needed in each page

Recommended: Use $routeChangeStart for centralized control.

Leave a Reply

Your email address will not be published. Required fields are marked *