CORS — nima, qanday sozlanadi, credentials, whitelist

~15 daq · Express · Autentifikatsiya va Xavfsizlik

CORS nima va nima uchun kerak?

9-darsda cors middleware ni ko'rdik — qo'shib ishlatdik. Lekin nima uchun kerakligi tushuntirilmadi. Bu darsda chuqurroq ko'ramiz.

Brauzerda xavfsizlik qoidasi bor: Same-Origin Policy. Bir sayt boshqa saytga so'rov yubora olmaydi. https://myapp.com da ishlayotgan JavaScript https://api.myapp.com ga so'rov yubora olmaydi — chunki domen boshqa.

Bu qoida nima uchun bor? Tasavvur qiling, siz bankingizga kirgansiz. Boshqa tabda zararli sayt ochiq. O'sha sayt sizning nomingizdan bankka so'rov yuborsa — xavfli. Same-Origin Policy bu hujumni to'xtatadi.

Lekin bu qoida qonuniy holatlarda ham to'sqinlik qiladi: https://myapp.com (frontend) https://api.myapp.com (backend) ga so'rov yubormoqchi — bloklaydi.

CORS (Cross-Origin Resource Sharing) — serverga "qaysi originlarga ruxsat beraman" deb aytish imkonini beradi.


Qanday ishlaydi?

Brauzer so'rov yuborishdan oldin serverga "preflight" so'rov yuboradi — OPTIONS metodi bilan. "Menga ruxsat bormi?" deb so'raydi. Server ruxsat bersa — asosiy so'rov yuboriladi.

Brauzer: OPTIONS /api/users
         Origin: https://myapp.com
         ↓
Server:  Access-Control-Allow-Origin: https://myapp.com
         ↓
Brauzer: "Ruxsat bor" → GET /api/users yuboradi

cors middleware bu headerlarni avtomatik qo'shadi.


Sozlash

const cors = require('cors');

// Development — hamma originlarga ruxsat:
app.use(cors());

// Production — faqat ma'lum originlarga:
app.use(cors({
  origin: ['https://myapp.com', 'https://www.myapp.com'],
}));

credentials — cookie va authorization header

Standart bo'yicha CORS so'rovlarda cookie va Authorization header yuborilmaydi. Agar kerak bo'lsa — ikki tomonda ham sozlash kerak.

Server tomonda:

app.use(cors({
  origin:      'https://myapp.com', // wildcard '*' ishlamaydi
  credentials: true,
}));

Frontend tomonda (fetch):

fetch('https://api.myapp.com/profile', {
  credentials: 'include', // cookie yuborish uchun
});

credentials: true bilan origin: '*' ishlamaydi — aniq origin ko'rsatilishi shart. Bu brauzerning qoidasi.


Dinamik whitelist

Bir nechta domen ruxsat berilishi kerak bo'lsa — massiv yoki funksiya:

const allowedOrigins = [
  'https://myapp.com',
  'https://admin.myapp.com',
  'http://localhost:3000', // development
];

app.use(cors({
  origin: (origin, callback) => {
    // origin yo'q bo'lsa — server-to-server so'rov (Postman, curl)
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error(`${origin} — ruxsat yo'q`));
    }
  },
  credentials: true,
}));

Tez-tez uchraydigan xatolar

credentials: true bilan origin: '*':

// Xato — brauzer qabul qilmaydi:
app.use(cors({ origin: '*', credentials: true }));

// To'g'ri:
app.use(cors({ origin: 'https://myapp.com', credentials: true }));

CORS ni route lardan keyin qo'yish:

app.get('/api/users', handler);
app.use(cors()); // kech — yuqoridagi route da CORS headerlari yo'q

CORS barcha route lardan oldin qo'yiladi.

Preflight so'rovni unutish:

OPTIONS so'rovlari ham CORS headerlarini talab qiladi. cors() middleware buni avtomatik hal qiladi — qo'lda yozilganda unutilishi mumkin.


Xulosa

CORS — brauzerning Same-Origin Policy qoidasini chetlab o'tish uchun server tomonidan ruxsat berish mexanizmi.

Development da cors() — hamma originlarga. Production da aniq originlar ko'rsatiladi. Cookie va auth header uchun credentials: true — origin: '*' bilan ishlamaydi.


Keyingi dars

29-dars: Input Validation — zod, joi bilan so'rovni tekshirish