XMLHttpRequest withCredentials POST, GET Авторизация с установкой куки и её отправкой в следующем запросе. Примеры запросов
Primary tabs
Рассмотрим ситуацию с кроссдоменными запросами, где у вас должна быть в том числе авторизация. В этом примере мой бэк находится "где-то" а запросы будут выполняться иного домена - а именно с http://example.com
Собственно говоря, должен работать вот такой код (пример json-авторизации, с получением куки и её и использованием в следующем GET-запросе):
// первый запрос для авторизации var domain = 'доменбэкэнда'; var xhr = new XMLHttpRequest(); xhr.open('POST', domain + 'api/v1/user/login', true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.withCredentials = true; // НУЖНО, иначе пришедшая в ответ кука не установится xhr.send('{"email":"myemail","password":"12345"}'); // второй запрос, запускайте после выполнения первого: // запрос данных с использованием куки, из предыдущего ответа var domain = 'доменбэкэнда'; var xhr = new XMLHttpRequest(); xhr.open('GET', domain + 'api/v1/user/current', true); xhr.withCredentials = true; xhr.send();
где:
- вместо
var domain = 'доменбэкэнда';
напишите например:
var domain = 'http://localhost:9121/';
или иной ваш домен.
-- пример можно запустить в консоли браузера, сначала один запрос, а потом и второй.
Что должен делать фронт
- По сути на чистом ли JS вы пишите или нет, не важно - главный момент состоит в том, чтобы в конечном итоге это транслировалось в опцию xhr.withCredentials = true не только для запросов чтения, использующих куки, но и для тех, что их получают (напр. метод авторизации выше - именно он должен получить от сервера заголовок Set-Cookie первый раз). Без этой опции куки из ответа сервера будут проигнорированы.
Что должен отдавать бэкэнд
На бэкэнде убедитесь, что (напр. смотря на приходящие заголовки в консоли браузера):
- Access-Control-Allow-Origin отдает тот домен, с которого идет запрос (или вообще любой, или что запрашиваете данные с чужого, но разрешенного домен - см. настройку в PHP)
Например:Access-Control-Allow-Origin: http://example.com
Примечание: В Сети указано, что нельзя отдавать просто * если вы используете Access-Control-Allow-Credentials: true (см. далее)
- Access-Control-Allow-Credentials должен быть установлен сервером в true
Access-Control-Allow-Credentials: true
- Проверьте на бэкэнде как вы устанавливаете куки в своем приложении, для ajax-запросов не подойдет SameSite: lux, в приложении нужно выставить
SameSite: none
НО: хотя на момент написания заметки это и работает, но в ближайшем будущем браузеры будут требовать для куков с опцией SameSite: none дополнительно ставить флаг Secure что автоматически потребует от вас запускать бэкэнд через https.
Пример заголовков, присываемых сервером, с которыми пример JS выше отработа хорошо для обоих запросов (вы тоже можете потестировать запросы к вашему приложению открыв веб-консоль инструментов разработчика в браузере на сайте example.com):
HTTP/1.1 200 OK
Date: Mon, 29 Jun 2020 10:50:36 GMT
Server: Apache/2.4.29 (Ubuntu)
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS
Access-Control-Max-Age: 1
Access-Control-Allow-Headers: Content-Type, Content-Range, Content-Disposition, Content-Description, X-AUTH-TOKEN
Cache-Control: max-age=0, must-revalidate, private
Content-Length: 518
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json
Для настройки севера, я использовал такие идеи/фрагменты кода.
withCredentials в JQuery
Как и в чистом javascript, withCredentials: true надо передавать в JQuery не только для использования куков запросом, но и при получении их в запросе авторизации, иначе они будут проигнорированы (т.е. фактически во всех ваших запросах, если они идут через ajax
).
Включается опция по схеме:
$.ajax({ url: a_cross_domain_url, xhrFields: { withCredentials: true } });
Источники/что почитать
- XMLHttpRequest Standart: https://xhr.spec.whatwg.org/#the-withcre...
- Особенности withCredentials: https://habr.com/ru/post/263417/
- ajax Разрешить запросы между разными доменами - cross-domain -- PHP: http://fkn.ktu10.com/?q=node/6889
- Log in to post comments
- 3017 reads