Handling Dropped Auth Headers on Axios Redirects
When an HTTP server responds with a redirect status code (such as
301, 302, or 307), HTTP clients like Axios often strip sensitive headers
such as Authorization before making the subsequent request.
This article explains why Axios and its underlying transport engines
drop authorization headers during redirects, how the behavior differs
across environments, and the specific implementation strategies you can
use to safely preserve authentication across redirected endpoints.
Why Authorization Headers Are Dropped
The stripping of authorization headers during redirects is a security
mechanism defined by standard HTTP specifications (RFC 7235 and RFC
9110). When a client sends credentials to
https://api.example.com, sending those same credentials to
a redirected destination (such as
https://untrusted-external-domain.com) could expose access
tokens, API keys, or basic authentication credentials to third
parties.
To prevent credential leakage:
- Cross-origin redirects: The
Authorizationheader is unconditionally stripped when the redirect target has a different protocol, domain, or port. - Same-origin redirects: Some environments preserve headers, but certain client libraries default to stripping sensitive headers regardless of the target unless explicitly configured otherwise.
How Axios Handles Redirects
The mechanism Axios uses to follow redirects depends directly on the runtime environment:
1. Node.js Environment
In Node.js, Axios relies on the follow-redirects package
to manage HTTP/HTTPS redirects. By default,
follow-redirects strips sensitive headers—including
authorization, cookie, and
proxy-authorization—whenever a redirect points to a
different hostname or protocol.
2. Browser Environment
In web browsers, Axios relies on the native
XMLHttpRequest or fetch APIs. The browser’s
network layer handles redirects automatically and transparently. Web
applications cannot modify browser-level redirect handling, and modern
browsers automatically strip the Authorization header on
cross-origin redirects according to the W3C Fetch specification.
Solutions for Preserving Authorization Headers
If you control the redirect target and require authentication credentials to persist, implement one of the following approaches based on your runtime environment.
Approach 1: Disable Automatic Redirects and Follow Manually (Node.js & Edge Runtimes)
The most reliable way to maintain control over headers during
redirects is to disable automatic redirect handling by setting
maxRedirects: 0. This allows you to inspect the
Location header and issue a new request with the required
credentials.
const axios = require('axios');
async function secureRedirectRequest(url, token) {
try {
const response = await axios.get(url, {
headers: { Authorization: `Bearer ${token}` },
maxRedirects: 0, // Prevent Axios from auto-following
validateStatus: (status) => status >= 200 && status < 400,
});
// Check if the response is a redirect (3xx status code)
if (response.status >= 300 && response.status < 400 && response.headers.location) {
const redirectUrl = new URL(response.headers.location, url).href;
// Verify destination is a trusted domain before attaching the token
const isTrustedOrigin = new URL(redirectUrl).hostname === 'trusted-api.example.com';
const newHeaders = isTrustedOrigin
? { Authorization: `Bearer ${token}` }
: {};
return axios.get(redirectUrl, { headers: newHeaders });
}
return response;
} catch (error) {
throw error;
}
}Approach 2: Use
beforeRedirect in Node.js
When running in Node.js, you can customize the underlying
follow-redirects behavior by providing a
beforeRedirect callback function inside your request
configuration:
const axios = require('axios');
axios.get('https://example.com/initial-endpoint', {
headers: {
Authorization: 'Bearer YOUR_ACCESS_TOKEN'
},
beforeRedirect: (options, responseDetails) => {
const targetHost = options.hostname;
// Explicitly re-attach the Authorization header if the target host is trusted
if (targetHost === 'trusted-redirect-target.com') {
options.headers.Authorization = 'Bearer YOUR_ACCESS_TOKEN';
}
}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));Approach 3: Axios Response Interceptors
You can also automate redirect handling globally across your application by defining an Axios response interceptor that catches 3xx statuses:
const instance = axios.create({
maxRedirects: 0,
validateStatus: (status) => status >= 200 && status < 400,
});
instance.interceptors.response.use(async (response) => {
if (response.status >= 300 && response.status < 400) {
const redirectUrl = response.headers.location;
const originalRequest = response.config;
// Optional: Add host validation here
return instance({
...originalRequest,
url: redirectUrl,
headers: {
...originalRequest.headers,
Authorization: originalRequest.headers.Authorization,
},
});
}
return response;
});Security Considerations
When re-applying authorization headers to redirected requests:
- Validate the target origin: Always parse the
Locationheader and verify that the destination hostname matches your trusted API domains. - Never re-attach tokens to third-party endpoints: Forwarding bearer tokens or credentials to external CDNs, storage buckets (like AWS S3), or partner services can lead to severe credential exposure.
- Enforce HTTPS: Never re-attach authentication headers if a redirect downgrades the connection from HTTPS to HTTP.