Asosiy kontentga o‘tish

Maqolalar 5 daqiqa 352 ko‘rish

CORS: brauzer aslida nimadan himoya qilyapti

CORS xatosi deyarli har bir dasturchining jig‘iga tekkan, lekin ko‘pchilik uni noto‘g‘ri tushunadi va StackOverflow'dan «allow all» ni ko‘chirib, o‘ziga eshik ochib qo‘yadi. Same-Origin Policy, preflight so‘rov va Django'da to‘g‘ri sozlashni tartib bilan ko‘ramiz.

security api backend

Mundarija

Bu manzara deyarli har bir jamoada takrorlanadi. Frontendchi kelib aytadi: "API'ing ishlamayapti, CORS xatosi beryapti". Backendchi shoshib StackOverflow'ni ochadi, birinchi topilgan javobni — CORS_ALLOW_ALL_ORIGINS = True — ko‘chiradi, xato yo‘qoladi va hamma xursand tarqaladi. Faqat bir narsa e'tibordan chetda qoladi: endi internetdagi istalgan sayt sizning API'ingizga foydalanuvchi nomidan so‘rov yubora oladi.

CORS shu qadar ko‘p jig‘iga tekkan mavzu bo‘lgani uchun uni bir marta chindan tushunib olishga arziydi. Chunki muammo aslida CORS'da emas, uni noto‘g‘ri tushunishda.

Avval Same-Origin Policy#

Hammasi brauzerdagi bitta qattiq qoidadan boshlanadi: bir saytda ishlab turgan JavaScript boshqa "origin"ga so‘rov yuborib, uning javobini o‘qiy olmaydi. Origin bu yerda protokol, domen va portning yig‘indisi:

Misol
https://solijonov.uz      va  https://api.solijonov.uz   → har xil origin
https://solijonov.uz      va  https://solijonov.uz:8000  → har xil origin

Bu qoida nega borligini bitta misol bilan tushunish oson. Aytaylik, siz bankingizga kirib turibsiz, sessiyangiz brauzerda ochiq. Boshqa tabda esa tasodifan yomon niyatli sayt ochilgan. Agar bu qoida bo‘lmasa, o‘sha yomon sayt o‘z JavaScript'i bilan bankingizning manziliga so‘rov yuborar va sizning sessiyangiz bilan javobni — masalan hisob balansini — o‘qib olardi. Same-Origin Policy aynan shuni to‘xtatadi. Ya'ni bu qoida sizga xalaqit berish uchun emas, sizni himoya qilish uchun bor.

Endi eng muhim jumla: CORS himoya emas, u himoyani nazorat ostida yumshatish usuli. Ya'ni "mening API'imga aynan mana bu origin'lardan so‘rov yuborishga ruxsat" deb aytishning yo‘li.

CORS qanday ishlaydi#

Brauzer boshqa origin'ga so‘rov yuborayotganda serverdan "ruxsatnoma" so‘raydi. Oddiy so‘rovda u javobning sarlavhasiga qaraydi:

Natija
Access-Control-Allow-Origin: https://solijonov.uz

Agar javobdagi bu sarlavhada so‘rov yuborgan origin ko‘rsatilgan bo‘lsa, brauzer JavaScript'ga javobni o‘qishga ruxsat beradi. Bo‘lmasa — javob serverdan muvaffaqiyatli kelgan bo‘lsa ham, brauzer uni JavaScript'dan yashiradi va konsolda o‘sha tanish CORS xatosini ko‘rsatadi.

Ba'zi so‘rovlarda esa qo‘shimcha bosqich bor. Masalan Content-Type: application/json bilan yuborilgan POST so‘rovdan oldin brauzer avval "razvedka" yuboradi — bu OPTIONS metodli preflight so‘rov. U serverdan "shu origin'dan, shu metod bilan kelsam bo‘ladimi?" deb so‘raydi. Server ruxsat beruvchi sarlavhalar bilan javob bersa, shundan keyingina asosiy so‘rov ketadi.

Bu yerda bir narsa chalg‘itadi: preflight'ga 200 kelishining o‘zi "ruxsat berildi" degani emas. Sinovda ro‘yxatda yo‘q origin'dan kelgan OPTIONS so‘rov ham 200 oldi — faqat javobda birorta Access-Control-* sarlavhasi bo‘lmadi, va brauzer asosiy so‘rovni yubormaydi. Shuning uchun CORS muammosini tekshirayotganda status kodga emas, javob sarlavhalariga qarang.

Ikki eng keng tarqalgan tushunmovchilik#

Birinchisi: "CORS server himoyasi". Yo‘q. CORS faqat brauzerdagi JavaScript'ni cheklaydi. curl, Postman yoki boshqa serverdan yuborilgan so‘rovga CORS umuman ta'sir qilmaydi — ular bemalol o‘tadi. Ya'ni CORS API'ingizni himoya qilmaydi, real himoya boshqa narsalarda: autentifikatsiya, ruxsatlar, rate limiting.

Ikkinchisi: "hammaga ruxsat bersam nima bo‘ladi?". Access-Control-Allow-Origin: * ochiq, cookie ishlatmaydigan API uchun — masalan ochiq ma'lumot beradigan API uchun — mutlaqo normal. Lekin cookie yoki sessiya bilan ishlaydigan API'da yulduzcha qo‘ysangiz, boshqa har qanday saytga foydalanuvchi sessiyasi bilan so‘rov o‘qishga eshik ochasiz. Brauzerlar buni shu qadar xavfli deb biladiki, "hammaga ruxsat" va "cookie bilan" birikmasini umuman bloklaydi. Uni chetlab o‘tish uchun har kelgan origin'ni ko‘r-ko‘rona qaytarib qo‘yish esa — bor xavfning eng yomon ko‘rinishi. Va bu "chetlab o‘tish" ba'zan o‘z-o‘zidan sodir bo‘ladi: pastdagi Django misolida buni sinab ko‘rsatamiz.

Django'da to‘g‘ri sozlash#

Amalda django-cors-headers ishlatiladi:

Python
INSTALLED_APPS = [..., "corsheaders"]
MIDDLEWARE = ["corsheaders.middleware.CorsMiddleware", ...]  # ro'yxatda tepada tursin

# Aniq ro'yxat — yulduzcha emas:
CORS_ALLOWED_ORIGINS = [
    "https://solijonov.uz",
    "https://app.solijonov.uz",
]
CORS_ALLOW_CREDENTIALS = True  # faqat cookie/sessiya kerak bo'lgan holatda

Qoida oddiy: ruxsat ro‘yxatida faqat siz ishonadigan real originlar tursin. Development uchun http://localhost:5173 kabi manzillarni ham qo‘shasiz, lekin uni kodga emas, muhit o‘zgaruvchisiga chiqarish ma'qul — production'da o‘sha lokal manzillar ro‘yxatda qolib ketmaydi.

Sozlashda ikkita jimgina tuzoq bor, ikkalasini ham sinab ko‘rdim.

Birinchisi — CORS_ALLOW_ALL_ORIGINS va CORS_ALLOW_CREDENTIALS birga. Brauzer "hammaga ruxsat + cookie" birikmasini bloklashini bilgan kutubxona bu holatda yulduzcha o‘rniga kelgan origin'ning o‘zini qaytaradi. Sinovda https://hujumchi.example dan yuborilgan so‘rov javobida shunday sarlavhalar keldi:

Natija
Access-Control-Allow-Origin: https://hujumchi.example
Access-Control-Allow-Credentials: true

Ya'ni brauzer bloklaydigan narsa emas, undan ham kengrog‘i: istalgan sayt foydalanuvchi sessiyasi bilan so‘rov yuborib, javobini o‘qiy oladi. Hech qanday xato ham chiqmaydi — shuning uchun bu sozlama juftligi eng xavflisi. Aniq ro‘yxat bilan esa o‘sha begona origin javobida birorta CORS sarlavhasi bo‘lmadi.

Ikkinchisi — middleware tartibi. CorsMiddleware ro‘yxatda CommonMiddleware dan pastda tursa, u yaratgan javoblarga sarlavha qo‘shilmay qoladi. Sinovda oxiriga slash qo‘yilmagan /ping manziliga kelgan so‘rov 301 bilan qaytdi va o‘sha javobda CORS sarlavhasi umuman bo‘lmadi — /ping/ esa joyida ishladi. Frontend uchun bu "ba'zi manzillarda CORS xatosi chiqadi, ba'zilarida yo‘q" degan chalkash manzara beradi.

Yodda qoladigan xulosa#

CORS'ni bir jumlaga siqish mumkin: Same-Origin Policy foydalanuvchini himoya qiladi, CORS esa siz o‘sha himoyada ongli ravishda ochadigan nazoratli eshik. Shuni tushunsangiz, "CORS xatosi" endi "API buzilgan" degan xavotir emas, "server bu origin'ga ruxsat bermagan" degan aniq xabar bo‘lib qoladi. Va "hammaga ruxsat + cookie" birikmasini hech qachon yozmang.

5 daqiqa 352 marta o‘qildi