Token Management
Secure Token Management
Secure token management is essential for protecting sensitive user data and maintaining the integrity of your application. This guide outlines best practices for handling tokens, such as access tokens and refresh tokens, in web applications.
Types of Tokens
Access Tokens
- Used for authenticating API requests.
- Short-lived, usually valid for minutes or hours.
Refresh Tokens
- Used to obtain new access tokens without requiring the user to re-authenticate.\
- Long-lived but should be securely stored.
Best Practices for Token Storage
Storing Access Tokens
- Store access tokens in memory for security.
- Do not store access tokens in localStorage or sessionStorage to avoid vulnerabilities such as XSS (Cross-Site Scripting).
Storing Refresh Tokens
- Store refresh tokens securely, such as in an HTTP-only cookie.
- HTTP-only cookies cannot be accessed by JavaScript, reducing the risk of XSS attacks.
Secure Token Transmission
Use HTTPS
- Always use HTTPS to encrypt token transmission.
- This prevents attackers from intercepting tokens via MITM (Man-in-the-Middle) attacks.
Set Secure and SameSite Flags
-
Use the Secure and SameSite attributes for cookies:
Token Expiry and Rotation
Access Token Expiry
- Use short expiration times for access tokens (e.g., 15 minutes).
- Promptly invalidate expired tokens on the server side.
Refresh Token Rotation
- Implement refresh token rotation to improve security.
- Each time a refresh token is used, issue a new refresh token and invalidate the old one.
Handling Token Revocation
Server-Side Revocation
- Maintain a blacklist of revoked tokens on the server.
- Check the blacklist during token validation.
Logout Handling
- Revoke tokens when the user logs out to prevent unauthorized access.
Preventing Token Theft
Protect Against CSRF
- Use anti-CSRF tokens for requests that modify data.
- Validate the CSRF token on the server.
Monitor for Anomalies
- Implement anomaly detection to monitor unusual token usage (e.g., multiple IPs).
Implementing Token Handling in React
Axios Interceptors for Token Refresh
Use Axios interceptors to attach access tokens to API requests and handle token refreshing:
import axios from "axios";
const apiClient = axios.create({
baseURL: "https://api.example.com",
});
apiClient.interceptors.request.use(async (config) => {
const token = getAccessToken(); // Fetch the token from memory or context
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
apiClient.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response.status === 401) {
const refreshToken = getRefreshToken(); // Fetch the refresh token from cookies
if (refreshToken) {
const newAccessToken = await refreshAccessToken(refreshToken);
setAccessToken(newAccessToken);
error.config.headers.Authorization = `Bearer ${newAccessToken}`;
return apiClient(error.config);
}
}
return Promise.reject(error);
}
);
export default apiClient;
Secure Context for Tokens
Use React Context or state management tools (e.g., Redux) to store tokens in memory.
Monitoring and Auditing
Token Logging
- Log token usage to detect anomalies.
- Ensure logs do not contain sensitive information like token values.
Regular Audits
- Conduct regular security audits of your token handling mechanisms.
By following these best practices, you can minimize the risks associated with token theft and ensure a secure user authentication flow in your React application.