🌐 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уfetchAPI).Access-Control-Max-Age: Вказує час (у секундах), протягом якого результати попереднього запиту (OPTIONS) можуть бути кешовані браузером. Це допомагає уникнути зайвих попередніх запитів для повторних крос-доменних запитів.Access-Control-Expose-Headers: Вказує список заголовків відповіді, які браузер повинен дозволити JavaScript-коду з клієнтської веб-сторінки читати. За замовчуванням браузер може обмежувати доступ до певних заголовків.
Як це працює (спрощений процес):
Крос-доменний запит: Коли JavaScript-код на веб-сторінці (наприклад,
https://client.example.com) намагається зробити запит до API на іншому домені (наприклад,https://api.example.com), браузер ініціює крос-доменний запит.Попередній запит (Preflight Request) - для складних запитів: Для певних "складних" запитів (наприклад, з методами, відмінними від GET, HEAD, POST з певними типами контенту, або з нестандартними заголовками), браузер спочатку відправляє попередній запит (preflight request) методом
OPTIONSдо сервера API. Цей запит включає заголовкиOrigin,Access-Control-Request-Method(який метод буде використано у фактичному запиті) та, можливо,Access-Control-Request-Headers(які нестандартні заголовки будуть використані).Відповідь на попередній запит: Сервер API отримує попередній запит і відповідає заголовками
Access-Control-Allow-Origin,Access-Control-Allow-MethodsтаAccess-Control-Allow-Headers, вказуючи свою політику CORS для цього походження.Прийняття або відхилення: Браузер аналізує заголовки відповіді на попередній запит. Якщо сервер дозволяє походження клієнта, метод та заголовки, браузер надсилає фактичний запит. Якщо сервер не дозволяє запит, браузер блокує фактичний запит і повідомляє про помилку.
Відповідь на фактичний запит: Після отримання фактичного запиту (якщо попередній запит був успішним або якщо запит був "простим"), сервер API обробляє його та повертає відповідь, обов'язково включаючи заголовок
Access-Control-Allow-Origin(щоб браузер знав, якому походженню дозволено читати цю відповідь).Перевірка відповіді браузером: Браузер перевіряє наявність та значення заголовка
Access-Control-Allow-Originу відповіді. Якщо походження клієнтської веб-сторінки відповідає значенню цього заголовка (або якщо значенням є*), браузер дозволяє JavaScript-коду отримати доступ до вмісту відповіді. В іншому випадку браузер блокує доступ, навіть якщо сервер успішно обробив запит.
Важливість CORS:
CORS є фундаментальним механізмом безпеки в сучасних веб-додатках. Він дозволяє контролювати, які веб-сайти можуть взаємодіяти з вашим API, запобігаючи потенційним атакам міжсайтового скриптингу (XSS) та іншим загрозам, які можуть виникнути внаслідок несанкціонованих міждоменних запитів. Правильне налаштування CORS на сервері API є обов'язковим для забезпечення безпеки та коректної роботи веб-додатків, що взаємодіють з API з інших доменів.