By default, cross-origin requests don't include cookies or HTTP authentication.
To send credentials, you must explicitly enable them on both client and server.
This is more restrictive than regular CORS — you can't use wildcards, and
the server must explicitly allow credentials.
Security Consideration
Sending credentials cross-origin has security implications. Only enable this
when you trust both the client origin and the server, and understand the
CSRF risks involved.
Client: Sending Credentials
const response = await fetch('https://api.example.com/user', {
credentials: 'include'
});
async function fetchUserProfile() {
const response = await fetch('https://api.example.com/profile', {
method: 'GET',
credentials: 'include',
headers: {
'Accept': 'application/json'
}
});
if (response.status === 401) {
window.location.href = '/login';
return;
}
return response.json();
}
Server: Allowing Credentials
import { createServer } from 'node:http';
const allowedOrigins = ['https://myapp.com', 'https://admin.myapp.com'];
const server = createServer((req, res) => {
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') {
res.writeHead(204);
res.end();
return;
}
const sessionId = parseCookies(req.headers.cookie).sessionId;
});
function parseCookies(cookieHeader) {
if (!cookieHeader) return {};
return Object.fromEntries(
cookieHeader.split('; ').map(c => c.split('='))
);
}
Key restrictions when using credentials:
Access-Control-Allow-Origin cannot be *
Access-Control-Allow-Credentials must be true
- Both client and server must opt-in
Credentials Mode Comparison
| Mode |
Same-Origin |
Cross-Origin |
Use Case |
omit |
No cookies |
No cookies |
Public APIs, no auth needed |
same-origin |
Sends cookies |
No cookies |
Default behavior (most apps) |
include |
Sends cookies |
Sends cookies |
Cross-origin auth (SSO, APIs) |
Setting Cookies Cross-Origin
res.setHeader('Set-Cookie', [
'sessionId=abc123',
'SameSite=None',
'Secure',
'HttpOnly',
'Path=/',
'Max-Age=86400'
].join('; '));
res.writeHead(200, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'https://myapp.com',
'Access-Control-Allow-Credentials': 'true',
'Set-Cookie': 'sessionId=abc123; SameSite=None; Secure; HttpOnly'
});
For cross-origin cookies, SameSite=None and Secure
are required. This means cookies only work over HTTPS.
Common Issues
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Set-Cookie', 'sessionId=abc123');
res.setHeader('Set-Cookie', 'sessionId=abc123; SameSite=None; Secure');
fetch('https://api.example.com/user');
fetch('https://api.example.com/user', { credentials: 'include' });
← Back to HTTP Examples