Завантажити API з файлом cookie


201

Я випробовую новий API Fetch, але у мене виникають проблеми з файлами cookie. Зокрема, після успішного входу є заголовок Cookie у майбутніх запитах, але Fetch, здається, ігнорує ці заголовки, і всі мої запити, зроблені за допомогою Fetch, несанкціоновані.

Це тому, що Fetch все ще не готовий або Fetch не працює з cookies?

Я будую свій додаток за допомогою Webpack. Я також використовую Fetch in React Native, у якого немає тієї самої проблеми.

Відповіді:


280

Fetch не використовує файли cookie за замовчуванням. Щоб увімкнути файл cookie, зробіть це:

fetch(url, {
  credentials: "same-origin"
}).then(...).catch(...);

55
аналогічне походження більше не працює, включайте (див. @ відповідь Джері): developers.google.com/web/updates/2015/03/introduction-to-fetch
jpic

7
@jpic: "включити" працює лише для запитів перехресного походження, але не для запитів того самого походження. Офіційні документи: github.com/github/fetch#sending-cookies
HoldOffHunger

Яка причина тоді мати файли cookie httponly, якщо вони читаються в js із завантаженням?
Мартін Байкар

4
Я вважаю same-origin(що робить ще роботу) означає , що все більше заголовків будуть поважати (печиво, і т.д.) , але ваш код буде мати обмежений доступ до відповіді.
Coderer

2
@JohnBalvinAriasThx. Як я пізніше зрозумів, наявність httpsly cookie означає, що вона не читається за допомогою document.cookie, але все ще доступна для запитів ajax або отримання.
Мартін Байкар

186

Окрім відповіді @ Ханетора, для тих, хто працює з запитами на поперечне походження: 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


9
як же встановити печиво?
pomo

2
Файл cookie встановлюється з боку сервера. У моєму випадку я використовував файли cookie httponly.
Ханетор

3
@Khanetor чи можу я встановити файли cookie за допомогою документа.cookie за допомогою JavaScript, а потім надіслати запит?
ospider

@ospider Ви можете надіслати його в шапці.
10101010

2
@ospider Я виявив, що достатньо лише встановити значення в document.cookie, щоб воно було включене в запити.
skwidbreth

36

Щойно вирішили. Всього дві f. дні брутфорсу

Для мене секрет полягав у наступному:

  1. Я зателефонував POST / api / auth і побачив, що файли cookie було успішно отримано.

  2. Потім зателефонувавши GET / api / users / з credentials: 'include'і отримав 401 невідповідно, оскільки жодного файлу cookie не було надіслано із запитом.

KEY - це також встановити credentials: 'include'перший /api/authдзвінок.


1
Я маю саме вашу проблему. Файл cookie сеансу ніколи не надсилається на запит даних GET. так 401. Я спробував Axios і Fetch. такий же результат. 2 можливості: POST для входу не зберігає отримане cookie або наступні дані GET не надсилає збережене cookie
Rhubarb65

@ Rhubarb65, щоб виграти це, слід вказати credentials: 'include'першимPOST /api/auth
user1671599

Так, у мене було це, але цього хочеться достатньо. Я використовую проксі-сервер devserver (клієнт Http)
Rhubarb65

Так, у мене були повноваження, але цього було недостатньо. Я використовував проксі-сервер Devserver, щоб пройти CORS: (клієнт http) - проксі - (сервер https). Я вважаю, що це означало, що cookie-файли з сервером не встановлені у веб-переглядачі, оскільки для безпечних файлів cookie потрібні https. Тож я додав прапор https: true у проксі-програмі Devserver, і це зафіксував
Rhubarb65

1
Добре ура. Ваша відповідь означала, що мені знадобилося лише 1 день грубої сили. :)
Михайло

16

Якщо ви читаєте це в 2019 році, credentials: "same-origin"це значення за замовчуванням.

fetch(url).then

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)));
    };
  }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.