Ambil API dengan Cookie


199

Saya mencoba API Ambil baru tetapi mengalami masalah dengan Cookie. Secara khusus, setelah login berhasil, ada header Cookie di permintaan masa depan, tetapi Ambil tampaknya mengabaikan header itu, dan semua permintaan saya yang dibuat dengan Ambil tidak sah.

Apakah karena Pengambilan masih belum siap atau Pengambilan tidak bekerja dengan Cookie?

Saya membangun aplikasi saya dengan Webpack. Saya juga menggunakan Fetch in React Native, yang tidak memiliki masalah yang sama.

Jawaban:


279

Ambil tidak menggunakan cookie secara default. Untuk mengaktifkan cookie, lakukan ini:

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

55
sama-asal tidak berfungsi lagi, termasuk tidak (lihat jawaban @ Jerry): developers.google.com/web/updates/2015/03/introduction-to-fetch
jpic

7
@ jpic: 'sertakan' hanya berfungsi untuk permintaan lintas-asal, tetapi tidak untuk permintaan asal-sama. Dokumen resmi: github.com/github/fetch#sending-cookies
HoldOffHunger

Apa alasannya untuk memiliki cookie httpon jika dapat dibaca dalam js dengan mengambil?
Martin Bajcar

4
Saya percaya same-origin(yang tidak masih bekerja) berarti bahwa lebih header akan dihormati (cookies, dll) tapi kode Anda akan memiliki akses terbatas ke respon.
Coderer

2
@JohnBalvinAriasThx. Seperti yang saya pahami kemudian, memiliki cookie httpon berarti itu tidak dapat dibaca oleh document.cookie, tetapi masih tersedia untuk ajax atau mengambil permintaan.
Martin Bajcar

184

Selain jawaban @ Khanetor, bagi mereka yang bekerja dengan permintaan lintas-asal: credentials: 'include'

Contoh permintaan pengambilan 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
bagaimana Anda mengatur cookie?
pomo

2
Cookie diatur dari sisi server. Dalam kasus saya, saya menggunakan cookie httponly.
Khanetor

3
@Khanetor, bisakah saya mengatur cookie menggunakan document.cookie dengan javascript, dan kemudian mengirim permintaan?
ospider

@ospider Anda dapat mengirimnya di header.
10101010

2
@ospider, saya menemukan bahwa hanya pengaturan nilai document.cookiesudah cukup untuk dimasukkan dalam permintaan.
skwidbreth

35

Baru saja dipecahkan. Hanya dua f. hari-hari brutforce

Bagi saya rahasianya adalah sebagai berikut:

  1. Saya menelepon POST / api / auth dan melihat bahwa cookie berhasil diterima.

  2. Kemudian memanggil GET / api / pengguna / dengan credentials: 'include'dan mendapat 401 tidak sah, karena tidak ada cookie yang dikirim dengan permintaan.

KUNCI untuk mengatur panggilan credentials: 'include'pertama /api/authjuga.


1
Saya punya masalah persis Anda. Cookie sesi tidak pernah dikirim pada permintaan data GET. jadi 401. Saya sudah mencoba Axios dan Fetch. hasil yang sama. 2 kemungkinan: POST login tidak menyimpan cookie yang diterima atau data GET berikut tidak mengirim cookie yang disimpan
Rhubarb65

@ Rhubarb65, untuk memenangkan ini kamu harus menentukan credentials: 'include'untuk yang pertamaPOST /api/auth
user1671599

Ya, saya sudah memilikinya tetapi cukup ingin. Saya menggunakan proxy devserver (client Http)
Rhubarb65

Ya, saya memiliki kredensial tetapi itu tidak cukup. Saya menggunakan proxy devserver untuk melewati CORS: (klien http) - proxy - (server https). Saya percaya ini berarti bahwa cookie sessionid dari server tidak disetel di browser karena cookie aman memerlukan https. Jadi saya menambahkan flag https: true di proxy devserver dan memperbaikinya
Rhubarb65

1
Bersorak sorai. Jawaban Anda berarti hanya butuh saya 1 hari bruteforce. :)
Michael

16

Jika Anda membaca ini di 2019, credentials: "same-origin"adalah nilai default.

fetch(url).then

1
Tetapi perhatikan bahwa tidak semua orang menggunakan browser yang cukup diperbarui. Saya menemukan pertanyaan ini karena versi Firefox saya sendiri (60.x, yang terbaru di Debian Stretch) tidak menetapkan itu secara default.
philh

2

Hanya menambahkan jawaban yang benar di sini untuk .net webapi2pengguna.

Jika Anda menggunakan corskarena situs klien Anda dilayani dari alamat yang berbeda dengan Anda, webapimaka Anda juga perlu memasukkan SupportsCredentials=truepada konfigurasi sisi server.

        // 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

Ini bekerja untuk saya:

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;
}

Kemudian buat panggilan Anda:

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)));
    };
  }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.