Получить API с Cookie

201

Я пробую новый Fetch API, но у меня проблемы с файлами cookie. В частности, после успешного входа в систему в будущих запросах есть заголовок Cookie, но Fetch, похоже, игнорирует эти заголовки, и все мои запросы, сделанные с помощью Fetch, не авторизованы.

Это потому, что Fetch все еще не готов или Fetch не работает с Cookies?

Я создаю свое приложение с помощью Webpack. Я также использую Fetch в React Native, который не имеет такой же проблемы.

Khanetor
источник

Ответы:

280

Fetch по умолчанию не использует cookie. Чтобы включить cookie, сделайте это:

fetch(url, {
  credentials: "same-origin"
}).then(...).catch(...);
Khanetor
источник
55
«
Тот
7
@jpic: «include» работает только для запросов из разных источников, но не для запросов из тех же источников. Официальные документы: github.com/github/fetch#sending-cookies
HoldOffHunger,
В чем же причина того, что у нас есть файлы cookie httponly, если они читаются в js с fetch?
Мартин Байкар
4
Я считаю same-origin(что все еще работает) означает, что будет учитываться больше заголовков (куки и т. Д.), Но ваш код будет иметь ограниченный доступ к ответу.
Coderer
2
@JohnBalvinAriasThx. Как я позже понял, наличие cookie httponly означает, что он не document.cookieдоступен для чтения , но все еще доступен для запросов ajax или fetch.
Мартин Байкар
186

В дополнение к ответу @ Khanetor, для тех, кто работает с запросами разных источников: credentials: 'include'

Пример запроса на выборку JSON:

fetch(url, {
  method: 'GET',
  credentials: 'include'
})
  .then((response) => response.json())
  .then((json) => {
    console.log('Gotcha');
  }).catch((err) => {
    console.log(err);
});

https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials

zurfyx
источник
9
как установить cookie?
Помо
2
Файл cookie устанавливается со стороны сервера. В моем случае я использовал файлы cookie httponly.
Ханетор
3
@Khanetor я могу установить куки, используя document.cookie от javascript, а затем отправить запрос?
Оспидер
@ospider Вы можете отправить его в шапке.
10101010
2
@ospider Я обнаружил, что достаточно просто установить значение в document.cookie, чтобы включить его в запросы.
Сквидбрет
36

Только что решили. Всего два ф. дни брутфорса

Для меня секрет был в следующем:

  1. Я позвонил в POST / api / auth и увидел, что куки были успешно получены.

  2. Затем, позвонив GET / api / users / with credentials: 'include'и получив 401 unauth, из-за отсутствия файлов cookie с запросом.

Ключ должен быть установлен credentials: 'include'для первого /api/authзвонка тоже.

user1671599
источник
1
У меня именно твоя проблема. Файл cookie сеанса никогда не отправляется в запросе данных GET. так 401. Я пробовал Аксиос и Фетч. тот же результат. 2 варианта: логин POST не хранит полученный файл cookie или следующие данные GET не отправляют сохраненный файл cookie
Rhubarb65
@ Rhubarb65, чтобы выиграть это вы должны указать credentials: 'include'для первогоPOST /api/auth
user1671599
Да, у меня было это, но этого достаточно. Я использую прокси-сервер devserver (клиент Http)
Rhubarb65
Да, у меня были полномочия, но этого было недостаточно. Я использовал прокси-сервер devserver, чтобы обойти CORS: (клиент http) - прокси - (сервер https). Я полагаю, это означало, что cookie-файл sessionid с сервера не был установлен в браузере, поскольку для безопасных cookie-файлов требуется https. Поэтому я добавил флаг https: true в прокси-сервер devserver, и это исправило его
Rhubarb65
1
Хорошо ура. Ваш ответ означал, что это заняло у меня всего 1 день грубой силы. :)
Майкл
16

Если вы читаете это в 2019 году, credentials: "same-origin"это значение по умолчанию.

fetch(url).then
alextrastero
источник
1
Но обратите внимание, что не все используют достаточно обновленный браузер. Я столкнулся с этим вопросом, потому что моя собственная версия Firefox (60.x, самая последняя в Debian Stretch) не устанавливает его по умолчанию.
Фил
2

Просто добавив правильные ответы здесь для .net webapi2пользователей.

Если вы используете, corsпотому что ваш клиентский сайт обслуживается с другого адреса, чем ваш, webapiто вам также необходимо включить SupportsCredentials=trueконфигурацию на стороне сервера.

        // Access-Control-Allow-Origin
        // https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
        var cors = new EnableCorsAttribute(Settings.CORSSites,"*", "*");
        cors.SupportsCredentials = true;
        config.EnableCors(cors);
Марк Дорниан
источник
0

Это работает для меня:

import Cookies from 'universal-cookie';
const cookies = new Cookies();

function headers(set_cookie=false) {
  let headers = {
    'Accept':       'application/json',
    'Content-Type': 'application/json',
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
};
if (set_cookie) {
    headers['Authorization'] = "Bearer " + cookies.get('remember_user_token');
}
return headers;
}

Затем создайте свой звонок:

export function fetchTests(user_id) {
  return function (dispatch) {
   let data = {
    method:      'POST',
    credentials: 'same-origin',
    mode:        'same-origin',
    body:        JSON.stringify({
                     user_id: user_id
                }),
    headers:     headers(true)
   };
   return fetch('/api/v1/tests/listing/', data)
      .then(response => response.json())
      .then(json => dispatch(receiveTests(json)));
    };
  }
aarkerio
источник