In modern web applications, user authentication is an essential feature. One common use case is to redirect users based on their authentication status. For example, you might want to redirect users who are not logged in to a login page and allow authenticated users to access restricted areas. AngularJS provides various ways to handle such redirections in single-page applications (SPAs).
In this guide, we will discuss how to implement redirection based on authentication status using AngularJS and its built-in features like $routeProvider
, $location
, $rootScope
, and services.
1. Setting Up Authentication in AngularJS
First, let’s outline the basic flow of authentication. Typically, in AngularJS, we use a service to manage user authentication. This service handles the login process, checks whether the user is authenticated, and stores the authentication status.
Authentication Service Example
Create a service that manages user authentication:
app.factory('AuthService', function($http, $q, $rootScope) {
var authStatus = false;
return {
login: function(credentials) {
// Assuming we make an API call to authenticate the user
return $http.post('/api/login', credentials)
.then(function(response) {
authStatus = true;
$rootScope.authenticated = true; // Store authenticated status in $rootScope
return response.data;
})
.catch(function() {
authStatus = false;
$rootScope.authenticated = false;
return $q.reject('Authentication failed');
});
},
logout: function() {
authStatus = false;
$rootScope.authenticated = false;
// Optionally, perform an API call to log out on the server-side
},
isAuthenticated: function() {
return authStatus;
}
};
});
In this example, the AuthService
has methods to login, logout, and check the authentication status. The $rootScope.authenticated
flag is used to keep track of the user’s authentication state globally across the application.
2. Redirecting Users Based on Authentication Status
You need to ensure that users who are not authenticated cannot access restricted routes or views. This can be achieved by using AngularJS’s routing system and intercepting route changes with $routeChangeStart
event to check for authentication.
Using $routeProvider to Define Routes
You can use $routeProvider
to define routes and configure access restrictions based on the authentication status.
app.config(function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'home.html',
controller: 'HomeController'
})
.when('/dashboard', {
templateUrl: 'dashboard.html',
controller: 'DashboardController',
resolve: {
auth: function(AuthService, $location) {
// Check if user is authenticated
if (!AuthService.isAuthenticated()) {
// Redirect to login page if not authenticated
$location.path('/login');
}
}
}
})
.when('/login', {
templateUrl: 'login.html',
controller: 'LoginController'
})
.otherwise({
redirectTo: '/home'
});
});
In this configuration:
- The
/dashboard
route has aresolve
block. This block checks if the user is authenticated before the route is activated. If not authenticated, the user is redirected to the login page. - The
auth
function inresolve
checks the authentication status using theAuthService
and redirects to the login page if necessary.
3. Intercepting Route Changes Using $rootScope.$on('$routeChangeStart')
You can also use $rootScope.$on('$routeChangeStart')
to catch every route change and handle the authentication check globally for the app.
app.run(function($rootScope, $location, AuthService) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
// If route requires authentication and user is not authenticated
if (next.$$route && next.$$route.resolve && next.$$route.resolve.auth) {
if (!AuthService.isAuthenticated()) {
// Prevent navigation and redirect to login page
event.preventDefault();
$location.path('/login');
}
}
});
});
In this example:
- The
$routeChangeStart
event is fired every time a route change happens. - The event checks if the route has a resolved
auth
object (which indicates the route requires authentication). - If the user is not authenticated, it prevents the navigation (
event.preventDefault()
) and redirects the user to the login page ($location.path('/login')
).
4. Implementing a Login Page
In your login page, you should handle the authentication process. For example, once the user successfully logs in, you should redirect them to the page they initially tried to access, or to a default page like the dashboard.
app.controller('LoginController', function($scope, $location, AuthService) {
$scope.login = function(credentials) {
AuthService.login(credentials).then(function() {
// Redirect to dashboard or previous page after successful login
$location.path('/dashboard');
}, function() {
// Handle failed login
alert('Login failed');
});
};
});
In this example, once the login is successful, the user is redirected to the /dashboard
route. If the login fails, you can show an error message.
5. Handling Session Expiry and Logout
A common requirement is to manage session expiry. If the user’s session expires or if they manually log out, you should ensure that they are redirected to a public page like the login page.
Logout Functionality
To handle logging out, you could use the logout
method in your AuthService
and clear the authentication status.
app.controller('LogoutController', function($scope, $location, AuthService) {
AuthService.logout();
$location.path('/home');
});
This would clear the authentication status and redirect the user to the home page or any other public page.
Session Expiry Check
To handle session expiry, you might periodically check the user’s session status with a service that manages session expiry. If the session expires, you can redirect the user to the login page.
For example, using an HTTP interceptor to check session expiry:
app.factory('AuthInterceptor', function($q, $location, AuthService) {
return {
responseError: function(response) {
if (response.status === 401) { // Unauthorized error
AuthService.logout();
$location.path('/login');
}
return $q.reject(response);
}
};
});
app.config(function($httpProvider) {
$httpProvider.interceptors.push('AuthInterceptor');
});
This example uses an HTTP interceptor to check for unauthorized responses (like expired sessions) and redirects the user to the login page.