The abc.com → dfg.com Problem
Your frontend and your API are on different domains. Here is exactly what the browser changes, and why.
This is the scenario the rest of the category solves. Your React app is served from https://abc.com. Your API lives at https://dfg.com. The moment the frontend calls the API, three separate browser mechanisms activate — and each one can break your authentication independently.
Origin, site, and why both matter
- Origin = scheme + host + port.
https://abc.comandhttps://dfg.comare different origins. This is what CORS cares about. - Site = the registrable domain (eTLD+1).
abc.comanddfg.comare different sites. This is what cookies care about.
Different origin means the browser will not let your JavaScript read the response unless the API opts in. Different site means every cookie involved is a third-party cookie, with everything that now implies.
The three mechanisms
- CORS. The browser sends the request but hides the response from your JavaScript unless the API returns
Access-Control-Allow-Origin. SendingAuthorizationalso triggers a preflightOPTIONSfirst. - Cookie scope.
dfg.comcan only set cookies fordfg.com. It cannot set one forabc.com— no header, no flag, no exception. This is the rule that decides the architecture. - SameSite. Even the
dfg.comcookie is only attached to a request initiated byabc.comif it is markedSameSite=None; Secure— and that makes it a third-party cookie that Safari blocks outright and Firefox partitions.
What CORS actually protects
A common misreading: CORS is not protecting your API. Anyone can call it with curl; there is no browser there to enforce anything. CORS protects the user's browser session from being read by a page they did not trust. CORS is not authentication. Your API still needs every check in this course.
Your three options
- Bearer tokens. No cookies, so no
SameSite, no third-party blocking. Needs CORS configured for theAuthorizationheader. Simplest thing that works cross-site. - Cross-site cookies with
SameSite=None; Secureplus credentialed CORS. Works today, breaks for some users, and is on a downward trajectory. - Stop being cross-site. Move the API to
api.abc.com, or proxy it throughabc.com/api. Cookies become first-party and every problem in this category disappears.
Option 3 is the one teams wish they had picked. The next lessons cover all three in detail.
Example
// From https://abc.com — this is a cross-origin, cross-site call
const res = await fetch('https://dfg.com/api/orders', {
credentials: 'include', // ask the browser to attach dfg.com cookies
});
// Three separate things must all be true for this to work with cookies:
//
// 1. dfg.com returns Access-Control-Allow-Origin: https://abc.com
// Access-Control-Allow-Credentials: true
// 2. the session cookie was set with SameSite=None; Secure
// 3. the user's browser has not blocked third-party cookies
//
// Miss any one and the request goes out ANONYMOUSLY — no error, just a 401.When to use it
- A team splits their Next.js frontend onto a CDN domain and their Laravel API onto another, and every logged-in request starts returning 401 in the browser but works in Postman.
- A public API is called by customer web apps from hundreds of unknown origins, so bearer tokens are the only workable scheme.
- An engineer proposes moving the API to api.abc.com and removes the entire CORS-plus-cookie problem in one DNS change.
More examples
Same site or not — the test that decides everything
Row two is the sweet spot most teams should aim for: separate deployments, separate scaling, and cookies that are still first-party.
Frontend API Same origin? Same site?
---------------------------------------------------------------------------
https://abc.com https://abc.com/api YES YES
https://abc.com https://api.abc.com no YES
https://app.abc.com https://api.abc.com no YES
https://abc.com https://dfg.com no no
https://abc.com:3000 https://abc.com:8000 no YES
http://abc.com https://abc.com no no (scheme)
# Same origin → nothing to configure at all.
# Same site → CORS needed for the browser; cookies still work normally (Lax).
# Different site → CORS needed AND cookies need SameSite=None; Secure,
# which browsers are actively restricting. Prefer tokens.What the browser reports when it goes wrong
The last case is the cruel one. There is no error to search for — you have to open the network tab and notice the missing Cookie request header.
# Missing Access-Control-Allow-Origin entirely
Access to fetch at 'https://dfg.com/api/orders' from origin 'https://abc.com'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is
present on the requested resource.
# Wildcard used together with credentials — not allowed, ever
The value of the 'Access-Control-Allow-Origin' header in the response must not
be the wildcard '*' when the request's credentials mode is 'include'.
# Server did not allow the Authorization header in the preflight
Request header field authorization is not allowed by
Access-Control-Allow-Headers in preflight response.
# And the silent one — no console error at all, just a 401:
# the cookie was simply not attached because it lacked SameSite=None; Secure,
# or because the browser blocks third-party cookies.
Discussion