Skip to content

🌐 CORS (Cross-Origin Resource Sharing): Контроль міждоменних запитів у браузері

Що це?

CORS (Cross-Origin Resource Sharing) - це механізм безпеки браузера, який регулює, чи дозволено веб-сторінці, завантаженій з одного походження (origin), робити запити до ресурсів (наприклад, API) на іншому походженні. Походження визначається комбінацією протоколу (HTTP/HTTPS), домену (example.com) та порту (якщо нестандартний).

Проблема "Same-Origin Policy":

За замовчуванням браузери застосовують політику Same-Origin Policy, яка забороняє JavaScript-коду, що виконується на одній веб-сторінці, робити запити до ресурсів з іншого походження. Це важливий механізм безпеки, спрямований на запобігання потенційним атакам, таким як міжсайтовий скриптинг (XSS) та викрадення даних.

Як CORS вирішує проблему:

CORS дозволяє серверу API явно вказати, які саме інші походження (домени) мають право робити до нього запити. Це досягається шляхом обміну спеціальними HTTP-заголовками між браузером клієнта та сервером API.

Основні CORS-заголовки:

Заголовки запиту (від браузера до сервера):

  • Origin: Заголовок запиту, який браузер автоматично додає при здійсненні крос-доменного запиту. Він вказує походження (протокол, домен та порт) веб-сторінки, з якої ініційовано запит.

Заголовки відповіді (від сервера API до браузера):

  • Access-Control-Allow-Origin: Обов'язковий заголовок відповіді, який вказує, яким походженням дозволено доступ до ресурсу. Значенням може бути:

    • Конкретне походження (наприклад, https://example.com). У цьому випадку доступ буде дозволено лише запитам з цього походження.
    • * (зірочка). Це означає, що доступ дозволено з будь-якого походження. Слід використовувати з обережністю!
  • Access-Control-Allow-Methods: Вказує, які HTTP-методи (GET, POST, PUT, DELETE, OPTIONS тощо) дозволені для крос-доменних запитів з вказаного в Access-Control-Allow-Origin походження.

  • Access-Control-Allow-Headers: Вказує список HTTP-заголовків запиту, які дозволено використовувати при здійсненні крос-доменного запиту. Це необхідно для нестандартних заголовків, які клієнт може додавати до своїх запитів.

  • Access-Control-Allow-Credentials: Булевий заголовок, який вказує, чи можуть крос-доменні запити включати куки (cookies) та заголовки авторизації (наприклад, Authorization). Якщо цей заголовок має значення true, клієнтський запит також повинен мати відповідну конфігурацію (наприклад, withCredentials = true у fetch API).

  • Access-Control-Max-Age: Вказує час (у секундах), протягом якого результати попереднього запиту (OPTIONS) можуть бути кешовані браузером. Це допомагає уникнути зайвих попередніх запитів для повторних крос-доменних запитів.

  • Access-Control-Expose-Headers: Вказує список заголовків відповіді, які браузер повинен дозволити JavaScript-коду з клієнтської веб-сторінки читати. За замовчуванням браузер може обмежувати доступ до певних заголовків.

Як це працює (спрощений процес):

  1. Крос-доменний запит: Коли JavaScript-код на веб-сторінці (наприклад, https://client.example.com) намагається зробити запит до API на іншому домені (наприклад, https://api.example.com), браузер ініціює крос-доменний запит.

  2. Попередній запит (Preflight Request) - для складних запитів: Для певних "складних" запитів (наприклад, з методами, відмінними від GET, HEAD, POST з певними типами контенту, або з нестандартними заголовками), браузер спочатку відправляє попередній запит (preflight request) методом OPTIONS до сервера API. Цей запит включає заголовки Origin, Access-Control-Request-Method (який метод буде використано у фактичному запиті) та, можливо, Access-Control-Request-Headers (які нестандартні заголовки будуть використані).

  3. Відповідь на попередній запит: Сервер API отримує попередній запит і відповідає заголовками Access-Control-Allow-Origin, Access-Control-Allow-Methods та Access-Control-Allow-Headers, вказуючи свою політику CORS для цього походження.

  4. Прийняття або відхилення: Браузер аналізує заголовки відповіді на попередній запит. Якщо сервер дозволяє походження клієнта, метод та заголовки, браузер надсилає фактичний запит. Якщо сервер не дозволяє запит, браузер блокує фактичний запит і повідомляє про помилку.

  5. Відповідь на фактичний запит: Після отримання фактичного запиту (якщо попередній запит був успішним або якщо запит був "простим"), сервер API обробляє його та повертає відповідь, обов'язково включаючи заголовок Access-Control-Allow-Origin (щоб браузер знав, якому походженню дозволено читати цю відповідь).

  6. Перевірка відповіді браузером: Браузер перевіряє наявність та значення заголовка Access-Control-Allow-Origin у відповіді. Якщо походження клієнтської веб-сторінки відповідає значенню цього заголовка (або якщо значенням є *), браузер дозволяє JavaScript-коду отримати доступ до вмісту відповіді. В іншому випадку браузер блокує доступ, навіть якщо сервер успішно обробив запит.

Важливість CORS:

CORS є фундаментальним механізмом безпеки в сучасних веб-додатках. Він дозволяє контролювати, які веб-сайти можуть взаємодіяти з вашим API, запобігаючи потенційним атакам міжсайтового скриптингу (XSS) та іншим загрозам, які можуть виникнути внаслідок несанкціонованих міждоменних запитів. Правильне налаштування CORS на сервері API є обов'язковим для забезпечення безпеки та коректної роботи веб-додатків, що взаємодіють з API з інших доменів.