← Back to microsoft/playwright
microsoft / playwright · Issue No. 42840
1.64.0-next (main @ 04e547b); also reproduces on 1.63.0
const http = require('http');
const { request } = require('playwright');
const server = http.createServer((req, res) => {
console.log(req.url, req.headers.cookie);
if (req.url === '/redirect') {
res.writeHead(302, { location: '/final' });
return res.end();
}
res.end('ok');
});
server.listen(0, '127.0.0.1', async () => {
const base = `http://127.0.0.1:${server.address().port}`;
const context = await request.newContext({ extraHTTPHeaders: { cookie: 'token=xyz' } });
await context.get(base + '/redirect');
await context.get(base + '/redirect', { headers: { cookie: 'token=abc' } });
await context.dispose();
server.close();
});
The cookie header is sent on the redirected request as well, the same as every other header passed through headers or extraHTTPHeaders. The documentation for the headers option says: "These headers will apply to the fetched request as well as any redirects initiated by it."
/redirect token=xyz
/final token=xyz
/redirect token=abc
/final token=abc
The redirect target receives no cookie at all:
/redirect token=xyz
/final undefined
/redirect token=abc
/final undefined
When the context cookie store has cookies for the target URL, those replace the explicit header on the redirected request instead.
_sendRequest in packages/playwright-core/src/server/fetch.ts adds cookies from the context store to options.headers unless a cookie header is already present, so an explicit header wins on the first hop. The redirect path then removes cookie from the headers unconditionally before following the redirect, because it cannot tell the caller's header apart from the ones it added itself. The next hop only gets whatever the cookie store holds for the new URL.
This affects playwright.request.newContext(), context.request and route.fetch(). A common case is a standalone request context with a session cookie copied from a browser and an endpoint that redirects, for example /login to /dashboard or /api/resource to /api/resource/: the second request goes out unauthenticated, and the failure is silent.
I intend to work on this and will send a PR.
- Operating System: Windows 11
- Node.js: 22.17.0
- Playwright: main @ 04e547b
Relay reads this issue against the repository's contribution signals: the files it is likely to touch, how the maintainers triage work this size, and what the first contribution would exercise.
The full analysis for this issue is still being assembled. Until then, the description above and the thread on GitHub are the most reliable context.