Заставить Axios автоматически отправлять файлы cookie в своих запросах

121

Я отправляю запросы от клиента на свой сервер Express.js с помощью Axios.

Я установил файл cookie на клиенте и хочу читать этот файл cookie из всех запросов Axios, не добавляя их вручную в запрос вручную.

Это пример моего клиентского запроса:

axios.get(`some api url`).then(response => ...

Я попытался получить доступ к заголовкам или файлам cookie, используя эти свойства на моем сервере Express.js:

req.headers
req.cookies

Ни один из них не содержал файлов cookie. Я использую промежуточное ПО для парсера файлов cookie:

app.use(cookieParser())

Как заставить Axios автоматически отправлять файлы cookie в запросах?

Редактировать:

Я устанавливаю cookie на клиенте следующим образом:

import cookieClient from 'react-cookie'

...
let cookie = cookieClient.load('cookie-name')
if(cookie === undefined){
      axios.get('path/to/my/cookie/api').then(response => {
        if(response.status == 200){
          cookieClient.save('cookie-name', response.data, {path:'/'})
        }
      })
    }
...

Хотя он также использует Axios, это не имеет отношения к вопросу. Я просто хочу встраивать файлы cookie во все свои запросы после установки файла cookie.

Кунок
источник
1
как вы установили cookie на клиенте? покажите пример кода, пожалуйста :)
Tzook Bar Noy
@TzookBarNoy Добавлен код, о котором идет речь
Kunok 05
Файлы cookie устанавливаются серверами с помощью Set-Cookie, а не клиентом, я думаю, вы имеете в виду чтение файла cookie на клиенте. Согласно протоколу Cookie, клиент должен включать заголовок Cookie в свои запросы к серверу, выдающему файлы cookie.
Hans Poo
Посмотрите этот stackoverflow.com/questions/53898031/…
Эндер Боннет

Ответы:

245

У меня была такая же проблема, и я решил ее с помощью withCredentialsсвойства.

XMLHttpRequest из другого домена не может устанавливать значения файлов cookie для своего собственного домена, если для параметра withCredentials не установлено значение true перед выполнением запроса.

axios.get('some api url', {withCredentials: true});
палец
источник
8
Если вы пытаетесь подключиться к приложению Express, вам нужно будет использовать cors и использовать эти настройки. Укажите источник запроса. app.use (cors ({учетные данные: истина, происхождение: ' localhost: 8080 '}));
DogCoffee
17
обратите внимание, что это будет работать только в том случае, если Access-Control-Allow-Originв заголовке ответа не задан подстановочный знак (*)
Джерри Чжан,
1
@JerryZhang Что ты имеешь в виду? Я столкнулся с той же проблемой, если Access-Control-Allow-Originона не настроена, *это означает, что я не буду делать запрос к этому серверу из-за права CORS
Самайо
5
В ответе необходимо установить Access-Control-Allow-Originзначение домена, из которого вы хотите сделать запрос XHR. например, https://a.comэто сервер, https://b.comэто клиент, https://b.comзагружается в чей-то браузер и используется XMLHTTPRequestдля отправки запроса https://a.com. В дополнение к настройке XMLHTTPRequest(инициирован https://a.com) withCredential: trueсервер - https://b.comтакже необходимо настроить так, чтобы заголовок ответа содержалAccess-Control-Allow-Origin: https://a.com
Джерри Чжан
У меня небольшая проблема с этим ... если у меня есть сервер b в качестве клиента (т.е. страница реакции), чем если я установлю это значение true, он отправит учетные данные a, а не учетные данные b ... LOL. .. Хорошо, это не смешно.
golddragon007
25

TL; DR:

{ withCredentials: true } или axios.defaults.withCredentials = true


Из документации axios

withCredentials: false, // default

withCredentials указывает, должны ли запросы управления доступом между сайтами выполняться с использованием учетных данных

Если вы пройдете { withCredentials: true }с вашим запросом, он должен работать.

Лучше было бы установить withCredentialsкак trueвaxios.defaults

axios.defaults.withCredentials = true

Фатих Ацет
источник
5
Отправка учетных данных с каждым запросом - плохая практика. Эти элементы управления существуют не просто так. Обращение к другому сервису, отправка всех ваших файлов cookie - независимо от того, используются ли они, - это готово для эксплуатации.
colm.anseo
2
@colminator будут отправлены только файлы cookie, в которых указан домен сервера. (По умолчанию они также не будут отправлены ни в какие поддомены, и возможна дальнейшая фильтрация на основе пути.) Фактически мы отправляем только серверные файлы cookie, которые были установлены сервером.
M3RS
15

Я не знаком с Axios, но, насколько мне известно, в javascript и ajax есть опция

withCredentials: true

Это автоматически отправит cookie на клиентскую сторону. Например, этот сценарий также создается с помощью паспортаjs, который устанавливает cookie на сервере.

РИТЕШ АРОРА
источник
11

Также важно установить необходимые заголовки в экспресс-ответе. Вот те, которые у меня сработали:

app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', yourExactHostname);
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  next();
});
Эйк Ребейн
источник
Добавление X-PINGOTHERв Access-Control-Allow-Headersбыло для меня обязательным (Node.js 6.9 с Express 4.16, Chrome 63). Проверьте сообщение JakeElder об этой проблеме на GitHub: github.com/axios/axios/issues/191#issuecomment-311069164
Frosty Z
5

Другое решение - использовать эту библиотеку:

https://github.com/3846masa/axios-cookiejar-support

который интегрирует поддержку "Tough Cookie" в Axios. Обратите внимание, что этот подход по-прежнему требует withCredentialsфлага.

машина-призрак
источник
5

для людей, которые все еще не могут его решить, этот ответ мне помог. ответ stackoverflow: 34558264

TL; DR; необходимо установить {withCredentials: true}как запрос GET, так и запрос POST (получение cookie) для обоих axios, а также для выборки.

the_dangoria
источник
1
Это очень важно. Я пропустил это в своем коде и провел много времени, задаваясь вопросом, почему { withCredentials: true }запрос GET не имеет никакого эффекта.
yogmk 03
1
Крайне важный! Существует много дискуссий о добавлении withCredentials: trueв конфигурацию запроса, но не об этой детали. Я потратил почти 2 дня, пытаясь решить проблему, пока не наткнулся на это
rantao
4

Как заставить Axios автоматически отправлять файлы cookie в запросах?

устанавливать axios.defaults.withCredentials = true;

или для какого-то конкретного запроса вы можете использовать axios.get(url,{withCredentials:true})

это приведет к ошибке CORS, если ваш 'Access-Control-Allow-Origin' установлен на подстановочный знак (*). Поэтому не забудьте указать URL-адрес происхождения вашего запроса.

например: если ваш интерфейс, который выполняет запрос, выполняется на localhost: 3000, установите заголовок ответа как

res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');

также установить

res.setHeader('Access-Control-Allow-Credentials',true);
прак
источник
3

Так что у меня была точно такая же проблема, и я потерял около 6 часов своей жизни на поиски, у меня был

withCredentials: true

Но браузер по-прежнему не сохранял файл cookie, пока по какой-то странной причине мне не пришла идея перетасовать настройку конфигурации:

Axios.post(GlobalVariables.API_URL + 'api/login', {
        email,
        password,
        honeyPot
    }, {
        withCredentials: true,
        headers: {'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'
    }});

Похоже, вы всегда должны сначала отправлять ключ withCredentials.

Луиджи Кордова Гранера
источник
3

Вы можете использовать withCredentialsсвойство для передачи файлов cookie в запросе.

axios.get(`api_url`, { withCredentials: true })

При установке { withCredentials: true }вы можете столкнуться с проблемой перекрестного происхождения. Чтобы решить эту проблему, вам нужно использовать

expressApp.use(cors({ credentials: true, origin: "http://localhost:8080" }));

Здесь вы можете прочитать о withCredentials

Сунил Гарг
источник
2

Вы путаете эти два мнения.

У вас есть "react-cookie" и "axios"

response-cookie => предназначен для обработки cookie на стороне клиента

axios => предназначен для отправки запросов ajax на сервер

Имея эту информацию, если вы хотите, чтобы файлы cookie со стороны клиента передавались и на стороне сервера, вам нужно будет соединить их вместе.

Примечание из файла Readme "react-cookie":

Изоморфные куки!

Чтобы иметь доступ к пользовательским файлам cookie во время рендеринга на сервере, вы можете использовать plugToRequest или setRawCookie.

ссылка на readme

Если это то, что вам нужно, отлично.

Если нет, прокомментируйте, чтобы я мог уточнить детали.

Тзук Бар Ной
источник
Что plugToRequestименно делает? Я думал, что для доступа к файлам cookie на сервере узла все, что нужно, - это cookie-parserпромежуточное программное обеспечение (при условии, что Express)?
geoboy