CORS - Cross-Origin Resource Sharing
Level: Beginner to Intermediate
CORS matters when a browser frontend such as React, Angular, Vue, or plain JavaScript calls your ASP.NET Core API from a different origin.
- Same-origin policy: Browser blocks requests to different domain (security feature, prevents XSS attacks)
- Origin definition: Scheme (http/https) + Domain (example.com) + Port (3000)
- Cross-origin request: Frontend on localhost:3000 calling API on localhost:5000 (different ports = different origin)
- CORS blocking: Browser blocks fetch/axios to different origin (prevents malicious JavaScript from stealing data)
- CORS solution: Backend allows specific origins (tells browser "this origin is trusted")
builder.Services.AddCors(): Register CORS policy in Program.cs- `builder.Services.AddCors(options => options.AddPolicy("AllowReact", policy => policy.WithOrigins("http://localhost:3000")))
app.UseCors("AllowReact"): Apply policy to middleware- Allowed origins: Single origin ("http://localhost:3000"), multiple (".example.com"), any ("" dangerous!)
- Preflight request: OPTIONS request before actual POST (browser asks "can I make this request?")
- Credentials: Cookies/JWT sent with request only if
AllowCredentials()enabled - School Management CORS: Frontend React app (localhost:3000) calls API (localhost:5000), API must allow
- Methods/Headers: CORS allows GET/POST/PUT/DELETE, Content-Type header for JSON
- Production CORS: Specific trusted frontend URLs (not "*"), enable credentials if using JWT tokens
- Common CORS mistakes: Using CORS("*") in production (anyone can call your API!), not enabling credentials for auth
The Common Problem
Your frontend runs here:
http://localhost:3000
Your API runs here:
https://localhost:5001
The browser says:
Blocked by CORS policy
This does not mean your API is down. It means the browser is enforcing security rules.
What is an Origin?
An origin is made of:
scheme + host + port
Examples:
| URL | Origin |
|---|---|
http://localhost:3000 | http + localhost + 3000 |
https://localhost:5001 | https + localhost + 5001 |
https://school.com | https + school.com + default 443 |
These are different origins:
http://localhost:3000
https://localhost:3000
http://localhost:5000
Scheme and port matter.
Same-Origin Policy
Browsers protect users using same-origin policy.
It prevents a website from freely reading data from another website unless that other website allows it.
Example:
Frontend: https://school-portal.com
API: https://api.school-portal.com
These are different origins, so CORS must allow the frontend.
What CORS Does
CORS tells the browser:
This frontend origin is allowed to call this API.
It is a browser security feature.
Server-to-server calls are not blocked by browser CORS because no browser is involved.
Enable CORS in ASP.NET Core
This allows the frontend at http://localhost:3000.
Middleware Order
Common order:
app.UseRouting();
app.UseCors("AllowSchoolFrontend");
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
CORS should run after routing and before authentication/authorization in typical controller APIs.
Development Policy
For local development:
policy.WithOrigins("http://localhost:3000", "http://localhost:5173")
.AllowAnyHeader()
.AllowAnyMethod();
React often uses 3000.
Vite often uses 5173.
Production Policy
For production, use exact frontend URLs.
policy.WithOrigins("https://school.nexcoding.com")
.AllowAnyHeader()
.AllowAnyMethod();
Avoid broad access.
Credentials and Cookies
If your frontend sends cookies or authentication credentials:
policy.WithOrigins("https://school.nexcoding.com")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
Important:
AllowCredentials requires specific origins.
Do not combine it with AllowAnyOrigin.
ASP.NET Core blocks unsafe combinations.
Preflight Requests
For some requests, the browser sends an OPTIONS request first.
This is called a preflight request.
It asks:
Is this method/header/origin allowed?
Common triggers:
- custom headers
- methods like PUT or DELETE
- content types other than simple form types
- authorization headers
ASP.NET Core CORS middleware handles preflight requests when configured correctly.
CORS is Not Authentication
CORS does not prove the user is logged in.
CORS only controls which browser origins can call your API.
You still need:
- authentication
- authorization
- validation
- HTTPS
- proper error handling
School App Example
Frontend:
https://portal.school.com
API:
https://api.school.com
CORS policy:
builder.Services.AddCors(options =>
{
options.AddPolicy("SchoolPortal", policy =>
{
policy.WithOrigins("https://portal.school.com")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
Common Mistakes
| Mistake | Better Approach |
|---|---|
Using AllowAnyOrigin() in production | Use exact origins |
| Thinking CORS secures the API fully | Still use auth and authorization |
| Forgetting port number | Include exact origin with port |
Putting UseCors in wrong order | Place it in the HTTP pipeline correctly |
| Allowing credentials for every origin | Use specific trusted origins |
| Debugging CORS from Postman | Test from browser/frontend |
Practice Task
Configure CORS for a local frontend:
- Allow
http://localhost:3000. - Allow any method.
- Allow any header.
- Add
UseCors()in the pipeline. - Test a frontend call to
GET /api/students.
Quick Recap
| Question | Answer |
|---|---|
| CORS applies mainly to? | Browser requests |
| Origin includes? | Scheme, host, port |
| Register CORS? | AddCors() |
| Use CORS? | UseCors() |
| Production origin rule? | Use exact trusted URLs |
| Credentials with any origin? | Do not do it |
Q: What is CORS and how do you enable it in ASP.NET Core?
Good Answer: "CORS, or Cross-Origin Resource Sharing, is a browser security mechanism that controls whether a frontend from one origin can call an API from another origin. An origin includes scheme, host, and port. In ASP.NET Core, CORS is configured with AddCors and applied with UseCors. In production, allowed origins should be specific trusted frontend URLs. AllowCredentials should never be combined with allowing every origin because that creates a security risk."
Use ChatGPT, Claude, or Copilot to go deeper on ASP.NET Core CORS. Try these prompts:
"Explain CORS using localhost frontend and API ports.""What is a preflight request?""Why is AllowAnyOrigin dangerous in production?""Show me a safe CORS policy for React frontend and ASP.NET Core API."
💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.