TL;DR
Your authentication token isn’t being sent in cross-origin requests because of how your browser handles CORS (Cross-Origin Resource Sharing). This guide shows you how to fix it by ensuring your server sends the correct headers and your client is configured properly.
Understanding the Problem
CORS is a security feature that prevents web pages from making requests to different domains than the one they were served from. If your API (server) doesn’t explicitly allow requests from your frontend (client), the browser will block them, and important information like authentication tokens won’t be included.
Solution Steps
- Server-Side Configuration: Add CORS Headers
- You need to tell your server which origins (domains) are allowed to access it. The most common header is
Access-Control-Allow-Origin. - Specific Origin: If you know the exact domain of your frontend, use that.
Access-Control-Allow-Origin: https://yourfrontenddomain.com - Wildcard (Not Recommended for Production): For development, you might use a wildcard to allow any origin, but this is a security risk in production.
Access-Control-Allow-Origin: * - Multiple Origins: Some servers allow specifying multiple origins. Check your server’s documentation for the correct syntax.
- Access-Control-Allow-Credentials: If you are sending cookies or authentication headers, you must set this to
true.Access-Control-Allow-Credentials: true - Access-Control-Allow-Methods: Specify the HTTP methods allowed (e.g., GET, POST, PUT, DELETE).
Access-Control-Allow-Methods: GET, POST, OPTIONS - Access-Control-Allow-Headers: Specify which headers are allowed in the request.
Access-Control-Allow-Headers: Content-Type, Authorization
- Ensure
withCredentialsis set totruein your fetch request. This tells the browser to include cookies and authentication headers.fetch('https://your-api-domain.com/data', { method: 'GET', headers: { 'Authorization': 'Bearer YOUR_TOKEN', 'Content-Type': 'application/json' }, withCredentials: true }) - Check your browser’s developer tools. Look in the Network tab for any CORS errors. The error message will usually tell you what header is missing or incorrect.
- If you see a preflight OPTIONS request failing, it means your server isn’t responding correctly to the initial CORS check.
- When making cross-origin requests with certain headers or methods (like PUT, DELETE, or custom headers), the browser first sends a preflight OPTIONS request to check if the server allows the request.
- Your server needs to handle this OPTIONS request and respond with the appropriate CORS headers.
// Example Node.js/Express handling of OPTIONS request app.use((req, res, next) => { if (req.method === 'OPTIONS') { res.header('Access-Control-Allow-Origin', '*'); // Or your specific origin res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.status(204).send(); // No content to send } else { next(); } });
- If you’re using cookies for authentication, make sure the
Access-Control-Allow-Credentials: trueheader is set on the server. - The
SameSiteattribute of your cookie also matters. If it’s set toStrictorLax, it might prevent cross-origin requests from working.- Consider setting it to
Noneif you need to allow cross-origin cookies (and ensure your site is served over HTTPS).
- Consider setting it to