Прежде чем описывать CORS, стоит упомянуть об ограничениях браузеров:
Правило одного источника принцип обеспечения безопасности, реализованный web браузерами для предотвращения запросов JavaScript кодом к другим источникам (т.е. к другим доменам).
Cross-Origin Resource Sharing (CORS) является техникой для ослабления безопасности, которая разделяет запросы на 2 вида:
Api обычно не состоит из простых запросов, потому что например:
Советую внимательно прочитать о каждом из запросов по ссылке выше, чтобы понимать, какими хедерами должен отвечать сервера на OPTION-запросы клиента.
Рассмотрим примеры каждого из видов запросов (запросы и ответы с необходимыми хедерами), где Client это js-код который выполняет запрос из браузера на домен отличный от текущего.



Чтобы совершить последний запрос (при котором на Server будут переданы учетные данные пользователя), Client при запросе обязан попросить браузера об этом с помощью параметра withCredentials, вот парочка примеров.
Пример js-кода:
var xmlhttp = new XMLHttpRequest();
xmlhttp.withCredentials = true;
xmlhttp.open("POST", "http://server-b.com/login");
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(JSON.stringify({email:'user@example.com', password:'p@ssword'}))
Пример для выполнения запроса из консоли:
fetch("http://server-b.com/login", {
"credentials": "include",
"headers": {
"accept": "application/json",
"content-type": "application/json"
},
"body": "{email:'user@example.com', password:'p@ssword'}",
"method": "POST",
"mode": "cors"
});тут "credentials": "include" это аналог withCredentials = true
Как видно Выше, если server-b собирается устанавливать свои куки и считывать их, то server-b на все OPTION-запросы должен отвечать хедером Access-Control-Allow-Credentials: true
1. Если Client работает на домене с портом, например http://foo.example:8888, то порт должен быть указан в Access-Control-Allow-Origin: http://foo.example:8888
2. Только для простого запроса в Access-Control-Allow-Origin можно указывать * (указывая на доступность всем).
3. В примере выше, заголовок Access-Control-Max-Age указывает на то, что этот предполетный ответ действует 84600 секунд, после которого должен быть выполнен новый предполетный запрос.
4. Проверить: в то же время клиенту будет доступна отправка настоящего DELETE запроса к ресурсу.
5. Проверить: некоторые JavaScript библиотеки, такие как AngularJS или Sencha Touch, отправляют предполетные запросы на любой дочерний запрос. Этот подход пожалуй безопаснее, потому что он не предполагает, что сервис придерживается семантик HTTP метода (т.е. GET endpoint мог быть написана с побочными эффектами).
cookie_httponly = 1 : теперь cookies сессий не будут доступны через скриптовые языки, например JavaScript