Браузер дотримується same-origin policy: JavaScript зі сторінки https://shop.example не може прочитати відповідь з https://api.other.example. CORS (Cross-Origin Resource Sharing) - механізм, яким сервер дозволяє браузеру послабити це обмеження для певних джерел.
Access-Control-Allow-Origin: https://shop.example
Access-Control-Allow-Methods: GET, POST, PATCH
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Allow-Credentials: true
Для «непростих» запитів (з Authorization, JSON-тілом, методами PUT/DELETE) браузер спершу надсилає preflight - OPTIONS-запит з питанням, чи можна. Access-Control-Max-Age дозволяє кешувати відповідь preflight.
Чому CORS - не захист API:
- Його виконує браузер.
curl, Postman, скрипт на сервері, мобільний застосунок CORS не перевіряють і отримують відповідь незалежно від заголовків. - CORS захищає користувача в браузері від того, щоб чужий сайт від його імені читав дані з вашого API. Але не захищає сам API від прямих запитів.
- Навіть із забороненим CORS простий запит (
POSTз формою) доходить до сервера й виконується - браузер лише не віддає скрипту відповідь. Тому від CSRF рятують токени й cookieSameSite, а не CORS.
Захист API - це автентифікація, авторизація, ліміти запитів, валідація.
Типові помилки налаштування:
Access-Control-Allow-Origin: *разом з credentials - браузер це не дозволяє.- Віддзеркалення будь-якого
Originз запиту у відповідь разом зAllow-Credentials: true- фактично дозволяє будь-якому сайту читати дані користувача.