Bagaimana cara membagikan cookie lintas asal? Lebih khusus lagi, bagaimana cara menggunakan Set-Cookie
tajuk yang dikombinasikan dengan tajuk Access-Control-Allow-Origin
?
Berikut penjelasan situasi saya:
Saya mencoba menyetel cookie untuk API yang dijalankan localhost:4000
di aplikasi web yang dihosting di localhost:3000
.
Sepertinya saya menerima header respons yang benar di browser, tetapi sayangnya header tersebut tidak berpengaruh. Ini adalah tajuk tanggapan:
HTTP / 1.1 200 Oke Access-Control-Allow-Origin: http: // localhost: 3000 Bervariasi: Asal, Terima-Enkode Set-Cookie: token = 0d522ba17e130d6d19eb9c25b7ac58387b798639f81ffe75bd449afbc3cc715d6b038e426adeac3316f0511dc7fae3f7; Usia Maks = 86400; Domain = localhost: 4000; Jalur = /; Kedaluwarsa = Sel, 19 Sep 2017 21:11:36 GMT; HttpOnly Jenis Konten: application / json; charset = utf-8 Panjang Konten: 180 ETag: W / "b4-VNrmF4xNeHGeLrGehNZTQNwAaUQ" Tanggal: Sen, 18 Sep 2017 21:11:36 GMT Koneksi: tetap hidup
Selain itu, saya dapat melihat cookie di bawah Response Cookies
saat saya memeriksa lalu lintas menggunakan tab Jaringan alat pengembang Chrome. Namun, saya tidak dapat melihat cookie disetel di tab Aplikasi di bawah Storage/Cookies
. Saya tidak melihat kesalahan CORS, jadi saya berasumsi saya melewatkan sesuatu yang lain.
Ada saran?
Perbarui I:
Saya menggunakan modul permintaan di aplikasi React-Redux untuk mengeluarkan permintaan ke /signin
titik akhir di server. Untuk server saya menggunakan express.
Server ekspres:
res.cookie ('token', 'xxx-xxx-xxx', {maxAge: 86400000, httpOnly: true, domain: 'localhost: 3000'})
Permintaan di browser:
request.post ({uri: '/ signin', json: {userName: 'userOne', password: '123456'}}, (err, response, body) => { // melakukan sesuatu })
Perbarui II:
Sekarang saya menyetel header permintaan dan tanggapan seperti orang gila sekarang, memastikan bahwa mereka ada baik dalam permintaan maupun tanggapan. Berikut tangkapan layarnya. Perhatikan header Access-Control-Allow-Credentials
, Access-Control-Allow-Headers
, Access-Control-Allow-Methods
dan Access-Control-Allow-Origin
. Melihat masalah yang saya temukan di github Axios , saya mendapat kesan bahwa semua header yang diperlukan sekarang telah disetel. Namun, masih belum berhasil ...
sumber
request
modul tersebut tidak dimaksudkan untuk digunakan di browser. Axios tampaknya melakukan pekerjaan dengan baik sejauh ini. Saya sekarang menerima header:Access-Control-Allow-Credentials:true
danAccess-Control-Allow-Origin:http://localhost:3000
(digunakan untuk mengaktifkan CORS). Ini sepertinya benar tetapiSet-Cookie
header tidak melakukan apa-apa ...{ withCredentials: true }
memang diperlukan oleh pihak Axios, header server juga harus diperiksa dengan cermat (lihat stackoverflow.com/a/48231372/488666 )Jawaban:
Apa yang kamu butuhkan
Agar berhasil menerima & mengirim cookie melalui permintaan CORS, lakukan hal berikut.
Back-end (server): Setel nilai header HTTP
Access-Control-Allow-Credentials
ketrue
. Selain itu, pastikan header HTTPAccess-Control-Allow-Origin
danAccess-Control-Allow-Headers
sudah disetel, bukan dengan karakter pengganti*
.Untuk info lebih lanjut tentang pengaturan CORS di express js baca dokumen di sini
Front-end (klien): Setel
XMLHttpRequest.withCredentials
flag ketrue
, ini bisa dilakukan dengan cara berbeda bergantung pada library request-response yang digunakan:jQuery 1.5.1
xhrFields: {withCredentials: true}
Pengambilan ES6 ()
credentials: 'include'
aksios :
withCredentials: true
Atau
Hindari penggunaan CORS bersamaan dengan cookie. Anda dapat mencapai ini dengan proxy.
Jika Anda karena alasan apapun jangan menghindarinya. Solusinya ada di atas.
Ternyata Chrome tidak akan menyetel cookie jika domain tersebut berisi porta. Mengaturnya untuk
localhost
(tanpa port) bukanlah masalah. Terima kasih banyak kepada Erwin atas tip ini!sumber
localhost
periksa ini di sini: stackoverflow.com/a/1188145 dan juga ini dapat membantu kasus Anda ( stackoverflow.com/questions/50966861/… )Access-Control-Allow-Origin
ke domain eksplisit, tidak hanya"*"
juga diperlukan. Maka itu akan menjadi jawaban yang sempurnaCatatan untuk Browser Chrome dirilis pada tahun 2020.
Jadi, jika server backend Anda tidak menyetel SameSite = None, Chrome akan menggunakan SameSite = Lax secara default dan tidak akan menggunakan cookie ini dengan permintaan {withCredentials: true}.
Info lebih lanjut https://www.chromium.org/updates/same-site .
Pengembang Firefox dan Edge juga ingin merilis fitur ini di masa mendatang.
Spec ditemukan di sini: https://tools.ietf.org/html/draft-west-cookie-incrementalism-01#page-8
sumber
Agar klien dapat membaca cookie dari permintaan lintas sumber, Anda harus memiliki:
Semua tanggapan dari server harus memiliki yang berikut di header mereka:
Access-Control-Allow-Credentials: true
Klien perlu mengirim semua permintaan dengan
withCredentials: true
opsiDalam implementasi saya dengan Angular 7 dan Spring Boot, saya mencapainya dengan yang berikut:
Sisi server:
Bagian tersebut
origins = "http://my-cross-origin-url.com"
akan ditambahkanAccess-Control-Allow-Origin: http://my-cross-origin-url.com
ke header respons setiap serverBagian tersebut
allowCredentials = "true"
akan ditambahkanAccess-Control-Allow-Credentials: true
ke header respons setiap server, yang kami butuhkan agar klien dapat membaca cookieSisi klien:
Dengan kelas ini Anda benar-benar memasukkan barang tambahan ke semua permintaan Anda.
Bagian pertama
req = req.clone({ withCredentials: true });
, adalah apa yang Anda butuhkan untuk mengirim setiap permintaan denganwithCredentials: true
opsi. Ini secara praktis berarti bahwa permintaan OPSI akan dikirim terlebih dahulu, sehingga Anda mendapatkan cookie dan token otorisasi di antara mereka, sebelum mengirim permintaan POST / PUT / DELETE yang sebenarnya, yang membutuhkan token ini dilampirkan padanya (di header), di perintah agar server memverifikasi dan menjalankan permintaan.Bagian kedua adalah bagian yang secara khusus menangani token anti-CSRF untuk semua permintaan. Membacanya dari cookie saat diperlukan dan menulisnya di header setiap permintaan.
Hasil yang diinginkan adalah seperti ini:
sumber
allowCredentials = "true"
di@CrossOrigin
anotasi membantu saya.Jawaban Pim sangat membantu. Dalam kasus saya, saya harus menggunakan
Jika ini adalah dateTime, meskipun tidak kedaluwarsa, tetap tidak akan mengirim cookie ke backend:
Semoga bermanfaat bagi orang-orang di masa depan yang mungkin menghadapi masalah yang sama.
sumber
Untuk ekspres, tingkatkan perpustakaan ekspres Anda
4.17.1
yang merupakan versi stabil terbaru. Kemudian;Dalam CorsOption: Set
origin
ke url localhost atau url produksi frontend dancredentials
untuktrue
misalnyaSaya mengatur asal saya secara dinamis menggunakan modul config npm .
Kemudian, di res.cookie:
Untuk localhost: Anda tidak perlu menyetel samaSite dan opsi aman sama sekali, Anda dapat menyetel
httpOnly
ketrue
untuk http cookie untuk mencegah serangan XSS dan opsi berguna lainnya tergantung pada kasus penggunaan Anda.Untuk lingkungan produksi, Anda perlu menyetel
sameSite
kenone
untuk permintaan lintas sumber dansecure
ketrue
. IngatsameSite
bekerja dengan versi ekspres terbaru hanya seperti saat ini dan versi chrome terbaru hanya mengatur cookie di atashttps
, sehingga perlu opsi aman.Inilah cara saya membuat milik saya dinamis
sumber