Add Cryptographic Timestamps in Axios Interceptors
This article demonstrates how to automatically intercept outgoing HTTP requests in Axios to generate and attach cryptographic timestamps. By leveraging Axios request interceptors alongside standard cryptographic hashing algorithms, you can secure API communications against replay attacks and guarantee payload integrity before any data leaves the client.
Understanding Axios Request Interceptors
Axios provides interceptors that allow you to modify requests before they are sent over the network. By attaching a request interceptor, you can dynamically read the request payload, generate a precise timestamp, compute a cryptographic signature using a shared secret, and inject both values into custom HTTP headers.
Implementation Example
The following example uses Node.js's built-in crypto
module (or an equivalent library like crypto-js for browser
environments) along with Axios to sign requests using HMAC-SHA256.
const axios = require('axios');
const crypto = require('crypto');
// Secret key shared between client and server
const API_SECRET = 'your-secure-shared-secret';
// Create a custom Axios instance
const apiClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
});
// Register the request interceptor
apiClient.interceptors.request.use(
(config) => {
// 1. Generate an ISO 8601 or UNIX millisecond timestamp
const timestamp = Date.now().toString();
// 2. Normalize the request method and body/params for signing
const method = config.method ? config.method.toUpperCase() : 'GET';
const payload = config.data ? JSON.stringify(config.data) : '';
const urlPath = config.url || '';
// 3. Create the canonical string to sign
const signaturePayload = `${timestamp}:${method}:${urlPath}:${payload}`;
// 4. Generate the cryptographic signature (HMAC-SHA256)
const signature = crypto
.createHmac('sha256', API_SECRET)
.update(signaturePayload)
.digest('hex');
// 5. Append headers to the outgoing request
config.headers['X-Timestamp'] = timestamp;
config.headers['X-Signature'] = signature;
return config;
},
(error) => {
return Promise.reject(error);
}
);
// Example usage
async function sendData() {
try {
const response = await apiClient.post('/v1/transactions', {
account: '12345',
amount: 100.0,
});
console.log('Response:', response.data);
} catch (error) {
console.error('Request failed:', error.message);
}
}
sendData();How It Works
- Timestamp Generation: The interceptor captures the
exact time the request is dispatched via
Date.now(). - Canonical String Construction: The HTTP method, request path, timestamp, and request body are concatenated into a predictable string structure.
- Cryptographic Hashing: The canonical string is signed using HMAC-SHA256 with a pre-shared secret key, generating a deterministic digest.
- Header Injection: The interceptor appends
X-TimestampandX-Signatureto the request'sheadersobject, passing the modified configuration down the Axios execution pipeline.
Server-Side Verification Rules
To complete the security implementation, the receiving server must validate the incoming headers:
- Clock Drift Validation: Reject any request where
the difference between the server's current time and
X-Timestampexceeds an acceptable threshold (typically 30 to 300 seconds) to prevent replay attacks. - Signature Matching: Reconstruct the same canonical
string from the incoming HTTP request and compute the HMAC-SHA256 hash
using the shared secret. If the computed hash does not strictly match
X-Signature, reject the request with an HTTP 401 Unauthorized status.