In AngularJS, when building an application that interacts with APIs that require authentication, it’s common to work with authentication tokens (like JWTs). These tokens are typically passed in HTTP headers to authorize API requests. One way to manage this is by using $httpInterceptor
, which allows you to globally intercept and modify HTTP requests and responses.
1. What is $httpInterceptor
?
$httpInterceptor
is a service in AngularJS that allows you to intercept HTTP requests and responses globally, before the request is sent to the server or after the response is received. You can use it to add authentication tokens to the request headers or handle errors globally, such as token expiration or unauthorized access.
2. When to Use $httpInterceptor
for Authentication Tokens?
- Inject Token into Request: When every API request needs to include an authentication token in the headers.
- Handle Token Expiry: If the token expires, you might want to automatically redirect the user to the login page or refresh the token.
- Global Error Handling: Handle errors like unauthorized (401) or forbidden (403) responses across the application.
3. Implementing $httpInterceptor
for Authentication Tokens
Step-by-Step Process
- Create the
$httpInterceptor
: You need to create an interceptor service that will intercept the HTTP requests and modify the headers before sending them. This is where you’ll add the authentication token. - Register the Interceptor: AngularJS allows you to register the interceptor globally using
$httpProvider.interceptors
. You can add it in your application’s configuration block. - Modify the Request with the Token: In the interceptor, check if the token exists (typically stored in
localStorage
orsessionStorage
) and add it to the request headers. - Handle Token Expiry or Unauthorized Access: In the response interceptor, handle scenarios where the server returns a 401 Unauthorized error (token expired or invalid).
4. Example: Using $httpInterceptor
for Authentication Tokens
Step 1: Create the Interceptor
angular.module('myApp', [])
.factory('authInterceptor', function($q, $location, $localStorage) {
return {
// Request Interceptor: Add token to headers
request: function(config) {
// Check if there is an auth token in localStorage
var token = $localStorage.get('auth_token');
// If token exists, add it to the request header
if (token) {
config.headers['Authorization'] = 'Bearer ' + token;
}
return config;
},
// Response Interceptor: Handle errors like unauthorized access
responseError: function(rejection) {
if (rejection.status === 401) {
// Token might have expired or is invalid
// Redirect the user to login page
$location.path('/login');
}
return $q.reject(rejection);
}
};
});
Step 2: Register the Interceptor
In your application’s config
block, you need to register the interceptor globally using $httpProvider.interceptors
. This ensures that the interceptor will be applied to every HTTP request.
angular.module('myApp', [])
.config(function($httpProvider) {
// Register the authInterceptor globally
$httpProvider.interceptors.push('authInterceptor');
});
Step 3: Storing the Authentication Token
Typically, the authentication token is received after a successful login and stored in localStorage
or sessionStorage
for future use. Here’s an example of how to store and retrieve the token:
angular.module('myApp')
.controller('LoginController', function($scope, $http, $localStorage) {
$scope.login = function(credentials) {
// Assuming the API returns a token on successful authentication
$http.post('/api/login', credentials)
.then(function(response) {
// Store the authentication token
$localStorage.set('auth_token', response.data.token);
// Redirect to home or dashboard
window.location.href = '/home';
})
.catch(function(error) {
// Handle login error
console.error('Login failed:', error);
});
};
});
Step 4: Handling Token Expiry or Unauthorized Access
In the $httpInterceptor
, the responseError
function handles HTTP errors. For example, if the server responds with a 401 Unauthorized error, you can assume that the token is either expired or invalid, and you can redirect the user to the login page.
responseError: function(rejection) {
if (rejection.status === 401) {
// Handle the case where the token is expired or invalid
console.log('Unauthorized access or token expired.');
$location.path('/login'); // Redirect to login page
}
return $q.reject(rejection); // Reject the response
}
Step 5: Logout and Token Removal
When a user logs out, you need to remove the token from storage so that it’s not sent in subsequent requests. You can clear the stored token like this:
angular.module('myApp')
.controller('LogoutController', function($scope, $localStorage) {
$scope.logout = function() {
// Remove the authentication token
$localStorage.remove('auth_token');
// Redirect to the login page
window.location.href = '/login';
};
});
5. Full Example with Authentication Token Handling
angular.module('myApp', ['ngStorage'])
.factory('authInterceptor', function($q, $location, $localStorage) {
return {
// Request Interceptor: Add token to headers
request: function(config) {
var token = $localStorage.get('auth_token');
if (token) {
config.headers['Authorization'] = 'Bearer ' + token;
}
return config;
},
// Response Interceptor: Handle 401 Unauthorized errors
responseError: function(rejection) {
if (rejection.status === 401) {
// Token is expired or invalid, redirect to login
$location.path('/login');
}
return $q.reject(rejection);
}
};
})
.config(function($httpProvider) {
// Register the interceptor
$httpProvider.interceptors.push('authInterceptor');
})
.controller('LoginController', function($scope, $http, $localStorage) {
$scope.login = function(credentials) {
$http.post('/api/login', credentials)
.then(function(response) {
// Store the token in localStorage
$localStorage.set('auth_token', response.data.token);
window.location.href = '/home'; // Redirect after successful login
})
.catch(function(error) {
console.error('Login failed:', error);
});
};
})
.controller('LogoutController', function($scope, $localStorage) {
$scope.logout = function() {
// Remove the token from localStorage
$localStorage.remove('auth_token');
window.location.href = '/login'; // Redirect to login page
};
});
6. Benefits of Using $httpInterceptor
for Authentication
- Centralized Authentication Logic: You don’t have to add the authentication token to every HTTP request manually; the interceptor does it for you.
- Token Expiry Handling: If the token expires or is invalid, you can handle the error globally, without needing to check for it in every request.
- Improved Security: Ensures the authentication token is sent automatically with every request to secure API endpoints.