CORS — policy, AllowAnyOrigin, specific origins, credentials
Muammodan boshlaylik
API https://api.dokon.uz da, React frontend https://dokon.uz da. Postman da hammasi ishlaydi. Brauzerda:
Access to fetch at 'https://api.dokon.uz/api/mahsulotlar' from origin 'https://dokon.uz'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present
on the requested resource.
Server javob berdi (log da 200 ko'rinadi), lekin brauzer JavaScript ga javobni bermadi.
Same-Origin Policy
Brauzer xavfsizlik qoidasi: bir origin dagi sahifa boshqa origin ga so'rov yuborib, javobni o'qiy olmaydi.
Origin = protokol + domen + port:
| URL | https://dokon.uz bilan bir xil origin mi? |
|---|---|
https://dokon.uz/savat |
✅ |
http://dokon.uz |
❌ protokol |
https://api.dokon.uz |
❌ domen (subdomen ham boshqa) |
https://dokon.uz:8443 |
❌ port |
Nega? Siz bank saytiga kirgansiz (cookie bor). Boshqa yovuz sayt ochilsa va u bank API siga so'rov yuborib javobni o'qisa — hisobingiz ma'lumotlari o'g'irlanardi. Same-origin policy buni to'xtatadi.
CORS (Cross-Origin Resource Sharing) — server brauzerga "bu origin larga ruxsat beraman" deb aytish mexanizmi.
Hayotiy o'xshatma
Yopiq turar-joy majmuasi. Qo'riqchi (brauzer) begona odamni (boshqa origin) ichkariga kiritmaydi. Lekin xonadon egasi (server) oldindan ro'yxat beradi: "dokon.uz dan kelgan kuryer menga kelishi mumkin". Qo'riqchi ro'yxatni tekshiradi. Ro'yxat yo'q — kiritmaydi. E'tibor bering: qo'riqchi — brauzer; to'g'ridan-to'g'ri devordan oshib o'tganlar (Postman, curl, boshqa server) uchun bu qoida yo'q.
ASP.NET Core da sozlash
const string FrontendPolicy = "Frontend";
builder.Services.AddCors(o =>
{
o.AddPolicy(FrontendPolicy, p => p
.WithOrigins("https://dokon.uz", "https://admin.dokon.uz")
.WithMethods("GET", "POST", "PUT", "DELETE")
.WithHeaders("Content-Type", "Authorization")
.SetPreflightMaxAge(TimeSpan.FromHours(1)));
});
var app = builder.Build();
app.UseRouting();
app.UseCors(FrontendPolicy); // Routing dan keyin, Authentication dan oldin
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
Origin lar — konfiguratsiyadan:
{ "Cors": { "Originlar": [ "https://dokon.uz", "https://admin.dokon.uz" ] } }
var originlar = builder.Configuration.GetSection("Cors:Originlar").Get<string[]>() ?? [];
o.AddPolicy(FrontendPolicy, p => p.WithOrigins(originlar).AllowAnyHeader().AllowAnyMethod());
Development da http://localhost:5173 (Vite) qo'shiladi, production da — yo'q.
Preflight so'rov
"Oddiy bo'lmagan" so'rovlar (JSON body, Authorization sarlavhasi, PUT/DELETE) oldidan brauzer avtomatik OPTIONS so'rov yuboradi:
OPTIONS /api/mahsulotlar/5
Origin: https://dokon.uz
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: authorization, content-type
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://dokon.uz
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Allow-Headers: Content-Type,Authorization
Access-Control-Max-Age: 3600
Ruxsat bo'lsa — haqiqiy PUT yuboriladi. SetPreflightMaxAge — brauzer javobni eslab qoladi va har safar OPTIONS yubormaydi.
Cookie bilan
Refresh token cookie da bo'lsa (62-dars):
p.WithOrigins("https://dokon.uz")
.AllowCredentials()
.AllowAnyHeader()
.AllowAnyMethod();
fetch("https://api.dokon.uz/api/auth/refresh", { method: "POST", credentials: "include" });
[!WARNING]
AllowAnyOrigin()vaAllowCredentials()ni birga ishlatib bo'lmaydi — ASP.NET Core xato beradi, va bu to'g'ri: istalgan sayt foydalanuvchi cookie lari bilan API ga so'rov yuborib, javobni o'qiy olardi.SetIsOriginAllowed(_ => true)bilan bu himoyani aylanib o'tish — jiddiy zaiflik. Ishonchli origin larni aniq sanab chiqing.
Endpoint darajasida
[EnableCors("OchiqApi")]
[HttpGet("ochiq/kurslar")]
public IActionResult Kurslar() => ...;
[DisableCors]
[HttpPost("ichki")]
public IActionResult Ichki() => ...;
app.MapGet("/api/ochiq", () => "...").RequireCors("OchiqApi");
CORS nimadan himoya qilmaydi
- CORS — brauzer qoidasi. curl, Postman, mobil ilova, boshqa server — CORS ga bo'ysunmaydi
- CORS — autentifikatsiya emas: API ni himoya qilish —
[Authorize]vazifasi (61-dars) AllowAnyOrigin()token bilan himoyalangan ochiq API uchun maqbul bo'lishi mumkin (cookie siz)
Tez-tez uchraydigan xatolar
UseCors noto'g'ri joyda (MapControllers dan keyin yoki UseAuthorization dan keyin) — preflight 401/404 oladi.
Origin oxirida /: "https://dokon.uz/" — mos kelmaydi; slash siz yozing.
Xatoni frontend da "tuzatish" — mode: "no-cors" javobni o'qib bo'lmas qiladi; muammo — server sozlamasida.
500 xatoda CORS sarlavhasi yo'q — brauzer haqiqiy xato o'rniga CORS xatosini ko'rsatadi; server log ini tekshiring.
Xulosa
Same-origin policy — brauzer boshqa origin (protokol + domen + port) javobini JavaScript ga bermaydi. CORS — server ruxsat beradigan origin larni e'lon qiladi. AddCors + nomlangan policy: WithOrigins, WithMethods, WithHeaders; UseCors — Routing dan keyin, Authentication dan oldin.
Preflight (OPTIONS) — oddiy bo'lmagan so'rovlar oldidan; SetPreflightMaxAge. Cookie — AllowCredentials + aniq origin lar (AllowAnyOrigin bilan emas). CORS — faqat brauzer himoyasi, autentifikatsiya o'rnini bosmaydi.
Keyingi dars
70-dars: Rate Limiting — so'rovlarni cheklash (.NET 7+)