Buat Axios mengirim cookie dalam permintaannya secara otomatis

121

Saya mengirim permintaan dari klien ke server Express.js saya menggunakan Axios.

Saya menetapkan cookie pada klien dan saya ingin membaca cookie itu dari semua permintaan Axios tanpa menambahkannya secara manual ke permintaan secara manual.

Ini adalah contoh permintaan sisi klien saya:

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

Saya mencoba mengakses header atau cookie dengan menggunakan properti ini di server Express.js saya:

req.headers
req.cookies

Tak satu pun dari mereka berisi cookie. Saya menggunakan middleware parser cookie:

app.use(cookieParser())

Bagaimana cara membuat Axios mengirim cookie dalam permintaan secara otomatis?

Edit:

Saya mengatur cookie pada klien seperti ini:

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:'/'})
        }
      })
    }
...

Meskipun juga menggunakan Axios, ini tidak relevan dengan pertanyaannya. Saya hanya ingin menyematkan cookie ke semua permintaan saya setelah cookie disetel.

Kunok
sumber
1
bagaimana Anda mengatur cookie pada klien? tolong tunjukkan contoh kode :)
Tzook Bar Noy
@TzookBarNoy Menambahkan kode yang dimaksud
Kunok
Cookie diatur oleh server dengan Set-Cookie bukan oleh klien, saya kira yang Anda maksud adalah membaca cookie di klien. Menurut protokol Cookie, klien harus menyertakan header Cookie dalam permintaannya ke server penerbit cookie.
Hans Poo

Jawaban:

241

Saya memiliki masalah yang sama dan memperbaikinya dengan menggunakan withCredentialsproperti.

XMLHttpRequest dari domain lain tidak dapat menyetel nilai cookie untuk domain mereka sendiri kecuali withCredentials disetel ke true sebelum membuat permintaan.

axios.get('some api url', {withCredentials: true});
fingerpich.dll
sumber
8
Jika Anda mencoba untuk terhubung ke aplikasi Express - Anda perlu menggunakan cors, dan menggunakan pengaturan ini. Asal permintaan diperlukan. app.use (cors ({credentials: true, origin: ' localhost: 8080 '}));
DogCoffee
17
perhatikan bahwa ini hanya akan berfungsi ketika Access-Control-Allow-Originheader respons tidak disetel ke wildcard (*)
Jerry Zhang
1
@JerryZhang Apa maksudmu? Saya menghadapi masalah yang sama, jika Access-Control-Allow-Origintidak disetel ke *itu berarti, saya tidak akan membuat permintaan ke server itu karena hak CORS
samayo
5
Respons perlu disetel Access-Control-Allow-Originke nilai domain tempat Anda ingin membuat permintaan XHR. misalnya https://a.comadalah server, https://b.comadalah klien, dan https://b.comdimuat di browser seseorang dan digunakan XMLHTTPRequestuntuk membuat permintaan https://a.com. Selain XMLHTTPRequest(diinisiasi https://a.com) untuk disetel withCredential: true, server - https://b.comjuga perlu dikonfigurasi agar header respons berisiAccess-Control-Allow-Origin: https://a.com
Jerry Zhang
Saya punya sedikit masalah dengan ini ... jika saya memiliki sebagai server b sebagai klien (mis. Halaman react), daripada jika saya menyetel ini ke true, itu akan mengirim kredensial, bukan kredensial b ... LOL. .. Oke, itu tidak lucu.
golddragon007
24

TL; DR:

{ withCredentials: true } atau axios.defaults.withCredentials = true


Dari dokumentasi axios

withCredentials: false, // default

withCredentials menunjukkan apakah permintaan Kontrol Akses lintas situs harus dibuat menggunakan kredensial atau tidak

Jika Anda lulus { withCredentials: true }dengan permintaan Anda, itu akan berhasil.

Cara yang lebih baik akan menetapkan withCredentialssebagai truediaxios.defaults

axios.defaults.withCredentials = true

Fatih Acet
sumber
5
Mengirim kredensial dengan setiap permintaan adalah praktik yang buruk. Kontrol ini ada karena suatu alasan. Berbicara ke layanan lain, mengirimkan semua cookie Anda - apakah cookie digunakan tidak, sudah matang untuk dieksploitasi.
colm.anseo
2
@colminator hanya cookie yang memiliki domain server sebagai domainnya yang akan dikirim. (Secara default, cookie tidak akan dikirim ke subdomain mana pun dan dapat dilakukan pemfilteran lebih lanjut berdasarkan jalur.) Akibatnya, kami hanya mengirimkan cookie server yang telah ditetapkan oleh server.
M3RS
15

Saya kurang paham dengan Axios, tapi setahu saya di javascript dan ajax ada opsi

withCredentials: true

Ini secara otomatis akan mengirim cookie ke sisi klien. Sebagai contoh, skenario ini juga dibuat dengan passportjs, yang menetapkan cookie di server

RITESH ARORA
sumber
11

Penting juga untuk menyetel tajuk yang diperlukan dalam tanggapan cepat. Ini adalah yang berhasil untuk saya:

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();
});
Eyk Rehbein
sumber
Saya wajib menambahkan X-PINGOTHERke dalam Access-Control-Allow-Headers(Node.js 6.9 dengan Express 4.16, Chrome 63). Periksa posting JakeElder tentang masalah GitHub ini: github.com/axios/axios/issues/191#issuecomment-311069164
Frosty Z
5

bagi orang-orang yang masih belum bisa menyelesaikannya, jawaban ini membantu saya. jawaban stackoverflow: 34558264

TLDR; seseorang perlu menyetel {withCredentials: true}permintaan GET dan juga permintaan POST (mendapatkan cookie) untuk axios dan juga fetch.

the_dangoria
sumber
1
Ini penting. Saya telah mengabaikan ini dalam kode saya dan menghabiskan banyak waktu bertanya-tanya mengapa { withCredentials: true }permintaan GET tidak berpengaruh apa pun.
yogmk
1
Sangat penting! Ada banyak diskusi tentang menambahkan withCredentials: trueke konfigurasi permintaan tetapi tidak detail ini. Saya menghabiskan hampir 2 hari mencoba untuk memecahkan masalah sampai saya menemukan ini
rantao
4

Bagaimana cara membuat Axios mengirim cookie dalam permintaan secara otomatis?

set axios.defaults.withCredentials = true;

atau untuk beberapa permintaan khusus yang dapat Anda gunakan axios.get(url,{withCredentials:true})

ini akan memberikan kesalahan CORS jika 'Access-Control-Allow-Origin' Anda disetel ke wildcard (*). Oleh karena itu, pastikan untuk menentukan url asal permintaan Anda

misalnya: jika front-end Anda yang membuat permintaan berjalan di localhost: 3000, maka setel header respons sebagai

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

juga diatur

res.setHeader('Access-Control-Allow-Credentials',true);
prak
sumber
3

Anda dapat menggunakan withCredentialsproperti untuk mengirimkan cookie dalam permintaan.

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

Dengan menyetelnya, { withCredentials: true }Anda mungkin mengalami masalah lintas sumber. Untuk mengatasinya, Anda perlu menggunakan

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

Di sini Anda dapat membaca tentang withCredentials

Sunil Garg
sumber
2

Anda mendapatkan dua pemikiran yang bercampur.

Anda memiliki "react-cookie" dan "axios"

react-cookie => digunakan untuk menangani cookie di sisi klien

axios => untuk mengirim permintaan ajax ke server

Dengan info itu, jika Anda ingin cookie dari sisi klien juga dikomunikasikan di sisi backend, Anda perlu menghubungkannya bersama.

Catatan dari "react-cookie" Readme:

Kue isomorfik!

Untuk dapat mengakses cookie pengguna saat melakukan rendering server, Anda dapat menggunakan plugToRequest atau setRawCookie.

tautan ke readme

Jika ini yang Anda butuhkan, bagus.

Jika tidak, mohon beri komentar agar saya bisa menjelaskan lebih lanjut.

Tzook Bar Noy
sumber
Apa plugToRequesttepatnya yang dilakukannya? Saya berpikir untuk mengakses cookie di server node, semua yang dibutuhkan adalah cookie-parsermiddleware (dengan asumsi Express)?
geoboy
2

Jadi saya memiliki masalah yang sama persis dan kehilangan sekitar 6 jam pencarian hidup saya, saya memiliki file

withCredentials: true

Tetapi browser masih tidak menyimpan cookie sampai karena beberapa alasan aneh saya punya ide untuk mengacak pengaturan konfigurasi:

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

Sepertinya Anda harus selalu mengirim Kunci 'withCredentials' terlebih dahulu.

Luigi Cordoba Granera
sumber