CORS: which websites may call the API
“What is CORS, and how do you configure it in ASP.NET Core?”
A browser rule, not a server lock: the API tells the browser which other websites' pages may read its answers.
See it
fetch POST
OPTIONS: POST + Authorization
1/6The Navistar portal wants to POST JSON with a token. First the browser asks the API: allowed?
In plain words
A web page's origin is its scheme, host and port: https://portal.navistar.example is one origin, https://api.navistar.example is another. Browsers follow the same-origin policy: JavaScript on a page may send a request to another origin, but may not read the answer unless that origin says it's allowed. Without this rule, any website you visit could quietly call your bank's API with your signed-in cookies and read the reply. CORS (Cross-Origin Resource Sharing) is how the API says who is allowed: it adds the header Access-Control-Allow-Origin: https://portal.navistar.example to its responses. The browser checks it and hands the answer to the page only if the page's origin is listed. For anything beyond a simple request (a GET or HEAD, or a POST with a form or plain-text body), such as a JSON body, an header, PUT or DELETE, the browser first sends a preflight: an request asking "may I?", and sends the real request only if the answer allows it. Credentials are cookies and other sign-in details the browser attaches on its own; a response may allow them only for exact, named origins. Two things to remember. CORS protects users in browsers; it is not a lock on the API: a script or Postman ignores it, and even a blocked browser GET still runs on the server. And it is configured in middleware, so its place in the pipeline matters.
- CORS relaxes the browser's same-origin policy: the server returns
Access-Control-Allow-Originand related headers, and the browser lets a page from that origin read the response. - Non-simple requests, like JSON bodies or an header, trigger a preflight request with
Access-Control-Request-Methodand-Headers; the browser sends the real request only if the preflight allows it. - In ASP.NET Core I define a named policy with listing exact origins, methods and headers, call after routing, which picks the endpoint, and before , and apply the policy to the endpoints. Origins come from config per environment.
- CORS is not access control: non-browser clients ignore it, so authentication and authorization still do the real protection. And with , which would let any site use a user's cookies, is refused by .NET at start-up.
In the lending API
The policy in Program.cs. Tap Next line.
Lending.sln · where this file sits
- src/Api/
options => is a short inline function that receives the settings.What they ask next
Interviewers check that you can explain every line. Tap a question to open it.
Why not ?
Any website could then read the API's answers in a user's browser. With cookies it's refused anyway: .NET throws at start-up if you combine with . The dangerous workaround is
SetIsOriginAllowed(_ => true)(a rule that says yes to every origin) with credentials, which echoes back whatever origin asks. List exact origins instead.The API returns 200 in the logs but the page shows a CORS error. Why?
The server ran the request; the browser refused to give the answer to the page because the allow header was missing or didn't match. Check the exact origin (scheme, host and port), that runs for that endpoint, and for preflights, that the method and headers are allowed.
A preflight asks for a header that isn't allowed. What does the server answer?
Still a 204, with
Access-Control-Allow-Originand anAccess-Control-Allow-Headerslist that holds only the allowed headers. The browser sees its header missing and blocks the real request.
Traps
- Don't say
CORS stops other people from calling our API.SayOnly pages in browsers. A script calls it anyway; authentication and authorization are the lock. - Don't say
Put after .SayBefore . Late, a preflight to an endpoint that needs auth can come back 401 instead of with its headers.