Authentication tokens (such as JWT – JSON Web Tokens) are crucial for securing user sessions in AngularJS applications. If not handled properly, tokens can be stolen, manipulated, or leaked, leading to unauthorized access.
This guide will cover:
- Understanding Authentication Tokens
- Storing Tokens Securely
- Transmitting Tokens Securely
- Using
$httpInterceptor
for Token Management - Handling Token Expiry and Refresh Tokens
- Preventing Token Theft (XSS & CSRF Protection)
- Logging Out and Token Revocation
- Best Practices for Secure Authentication
1. Understanding Authentication Tokens
Authentication tokens are used to verify a user’s identity without storing session data on the server.
Example of a JWT Token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VySWQiOiIxMjM0NTY3ODkwIiwicm9sZSI6ImFkbWluIn0.
hJ_WPrJ1f9GsgyJx3jwbc79MK0XhTToXZNQWxE0eXQo
A JWT consists of three parts:
- Header → Algorithm & token type
- Payload → User information (e.g., user ID, role)
- Signature → Cryptographic verification
Risks:
- If stored in
localStorage
, it is vulnerable to XSS attacks. - If transmitted over HTTP, it is interceptable by attackers.
- If not refreshed properly, session hijacking can occur.
2. Storing Tokens Securely
Avoid Storing Tokens in LocalStorage
Insecure:
localStorage.setItem('authToken', token);
Why?
- LocalStorage is accessible via JavaScript, making it vulnerable to XSS attacks.
- If an attacker injects a malicious script, they can steal tokens.
Use HttpOnly & Secure Cookies Instead
document.cookie = "authToken=" + token + "; Secure; HttpOnly; SameSite=Strict";
🔹 HttpOnly: Prevents JavaScript from accessing the token.
🔹 Secure: Ensures transmission only over HTTPS.
🔹 SameSite=Strict: Protects against CSRF attacks.
3. Transmitting Tokens Securely
Always Use HTTPS
Ensure your AngularJS app is running over HTTPS to encrypt data in transit.
$http.get('https://secure-api.com/data', { headers: { 'Authorization': 'Bearer ' + token }});
Send Tokens in HTTP Headers
Instead of passing tokens via query parameters (?token=xyz
), use Authorization headers:
$http.defaults.headers.common['Authorization'] = 'Bearer ' + token;
This prevents exposure in browser history and logs.
4. Using $httpInterceptor
for Token Management
Automatically Attach Tokens to Requests
Create an AngularJS interceptor to attach tokens automatically to API requests.
app.factory('authInterceptor', function($q, $injector) {
return {
request: function(config) {
var token = sessionStorage.getItem('authToken');
if (token) {
config.headers.Authorization = 'Bearer ' + token;
}
return config;
},
responseError: function(response) {
if (response.status === 401) {
// Redirect to login if token is invalid
$injector.get('$state').go('login');
}
return $q.reject(response);
}
};
});
app.config(function($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
});
Automatically adds the token to all API requests.
Handles unauthorized (401) responses gracefully.
5. Handling Token Expiry and Refresh Tokens
Check Token Expiration Before Making Requests
Decode the JWT payload and check the exp
(expiration) claim before using the token.
function isTokenExpired(token) {
var payload = JSON.parse(atob(token.split('.')[1]));
return payload.exp < Date.now() / 1000;
}
Use Refresh Tokens to Extend Sessions
- Instead of logging the user out when the token expires, use a refresh token.
- Store refresh tokens in HttpOnly cookies and exchange them for new access tokens.
Example:
$http.post('/refresh-token', { token: refreshToken }).then(function(response) {
sessionStorage.setItem('authToken', response.data.token);
});
6. Preventing Token Theft (XSS & CSRF Protection)
Prevent XSS Attacks (Cross-Site Scripting)
Sanitize user input before displaying it:
app.controller('MainController', function($scope, $sanitize) {
$scope.safeContent = $sanitize(userInput);
});
Never use innerHTML
with user-generated content.
Use CSRF Protection for API Requests
Enable CSRF protection in the backend and send CSRF tokens with API calls.
$http.defaults.headers.common['X-CSRF-Token'] = csrfToken;
Prevents unauthorized requests from malicious sites.
7. Logging Out and Token Revocation
Delete Tokens Securely on Logout
document.cookie = "authToken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; Secure; HttpOnly";
Ensures the token cannot be reused.
Blacklist Tokens on the Server
To prevent reuse of stolen tokens, maintain a blacklist of revoked tokens.
app.post('/logout', function(req, res) {
tokenBlacklist.add(req.token);
res.sendStatus(200);
});