Protecting AngularJS routes using authentication guards

Loading

In modern web applications, user authentication and authorization play a critical role in securing sensitive routes and resources. AngularJS provides several techniques to restrict access to specific routes based on whether the user is authenticated or authorized. One of the most common ways to implement this is by using route guards.

Route guards allow you to control navigation in your AngularJS application. By implementing authentication guards, you can protect routes that require a user to be authenticated or authorized before accessing them.

Why Protect Routes?

Routes in web applications are often associated with different user roles and permissions. For instance:

  • Admin-only routes: Some routes should only be accessible by admin users.
  • Authenticated routes: Some routes should only be accessible if the user is logged in.
  • Public routes: Some routes can be accessed without any restrictions.

Protecting these routes ensures that only authorized users can access sensitive areas of the application, while unauthorized users are redirected or shown an error page.

Steps to Protect Routes in AngularJS

There are multiple ways to protect routes in AngularJS, and this process generally involves:

  1. Defining a way to check if a user is authenticated.
  2. Creating a route guard that intercepts navigation and checks for authentication.
  3. Redirecting the user based on the result of the authentication check.

In AngularJS, the $routeProvider and $rootScope can be leveraged to define authentication checks for routes.

1. Define Authentication Service

The first step is to create a service that will handle authentication logic, such as checking whether the user is logged in, and storing the authentication state (e.g., via a session, token, or localStorage).

Example Authentication Service:

angular.module('app')
.factory('AuthService', function($http, $q) {
var isAuthenticated = false;

return {
login: function(credentials) {
// Perform login via API call and check response
return $http.post('/api/login', credentials).then(function(response) {
isAuthenticated = true;
return response.data;
});
},
logout: function() {
isAuthenticated = false;
},
isAuthenticated: function() {
return isAuthenticated;
}
};
});
  • isAuthenticated(): Returns true if the user is logged in, otherwise false.
  • login(): Simulates the login API call to authenticate a user.
  • logout(): Clears the authentication state when the user logs out.

2. Implement Authentication Guard

An authentication guard is a function or service that checks whether the user is authenticated before navigating to a protected route. If the user is not authenticated, they will be redirected to the login page or any other defined route.

You can use $rootScope to manage route changes and prevent access to certain routes based on authentication.

Example Route Guard using $rootScope.$on('$routeChangeStart'):

angular.module('app')
.run(function($rootScope, $location, AuthService) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
// Check if the route requires authentication
if (next.requiresAuth && !AuthService.isAuthenticated()) {
// Redirect the user to the login page if they are not authenticated
$location.path('/login');
}
});
});
  • $rootScope.$on('$routeChangeStart'): Listens for route changes. This function will be called before each route change.
  • next.requiresAuth: The next route configuration may have a property called requiresAuth, which tells whether authentication is required for that route.
  • AuthService.isAuthenticated(): Calls the authentication service to check if the user is authenticated.

3. Set Up Routes with Authentication Requirements

Once you have the authentication service and guard in place, you can now configure the routes. You can use the requiresAuth property on the route to specify whether that route requires authentication.

Example Route Configuration with $routeProvider:

angular.module('app')
.config(function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'home.html',
controller: 'HomeController',
requiresAuth: true // Protect this route
})
.when('/login', {
templateUrl: 'login.html',
controller: 'LoginController'
})
.otherwise({
redirectTo: '/login'
});
});
  • requiresAuth: true: This indicates that the user must be authenticated to access the /home route. If they are not authenticated, they will be redirected to the login page.

4. Redirecting Unauthorized Users

When an unauthenticated user attempts to access a protected route, you should redirect them to a login page. The authentication guard will handle this for you by listening to route changes and redirecting the user if needed.

Example Redirect in Route Guard:

If a user tries to access a protected route without being authenticated, they will be redirected to the login page.

angular.module('app')
.run(function($rootScope, $location, AuthService) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
// If the route requires authentication and the user is not authenticated
if (next.requiresAuth && !AuthService.isAuthenticated()) {
// Redirect to login page
$location.path('/login');
}
});
});

This logic ensures that if an unauthenticated user tries to access a route that requires authentication, they will be sent to the login page.

5. Handling Authorization (Optional)

In some cases, you may want to implement not only authentication but also authorization. For example, certain routes may only be accessible to users with specific roles (admin, user, etc.).

You can expand the authentication guard logic to include role checks as well.

Example with Role-based Authorization:

In the AuthService, you could add a getUserRole() method:

angular.module('app')
.factory('AuthService', function() {
var userRole = 'admin'; // Example, you should get this info from the backend

return {
isAuthenticated: function() {
// Check if the user is authenticated
return true; // Simulate the authentication check
},
getUserRole: function() {
return userRole; // Simulate getting the user role
}
};
});

Now, in the route guard, you can check both authentication and the user’s role before allowing access to the route:

angular.module('app')
.run(function($rootScope, $location, AuthService) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
// Check if the route requires authentication and the user is authenticated
if (next.requiresAuth && !AuthService.isAuthenticated()) {
$location.path('/login');
}
// Check if the route requires a specific role
else if (next.requiredRole && AuthService.getUserRole() !== next.requiredRole) {
$location.path('/unauthorized');
}
});
});

Leave a Reply

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