Handling Authentication Tokens Securely in AngularJS

Loading

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:

  1. Understanding Authentication Tokens
  2. Storing Tokens Securely
  3. Transmitting Tokens Securely
  4. Using $httpInterceptor for Token Management
  5. Handling Token Expiry and Refresh Tokens
  6. Preventing Token Theft (XSS & CSRF Protection)
  7. Logging Out and Token Revocation
  8. 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:

  1. Header → Algorithm & token type
  2. Payload → User information (e.g., user ID, role)
  3. 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);
});

Leave a Reply

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