tl; dr; Tentang Kebijakan Asal yang Sama
Saya memiliki proses Grunt yang memulai sebuah instance dari server express.js. Ini bekerja dengan sangat baik sampai sekarang ketika itu mulai menyajikan halaman kosong dengan yang berikut ini muncul di log kesalahan di konsol pengembang di Chrome (versi terbaru):
XMLHttpRequest tidak dapat memuat https://www.example.com/ Tidak ada header 'Access-Control-Allow-Origin' pada sumber yang diminta. Oleh karena itu, asal ' http: // localhost: 4300 ' tidak diizinkan untuk diakses.
Apa yang mencegah saya mengakses halaman ini?
javascript
cors
same-origin-policy
Peter David Carter
sumber
sumber
Jawaban:
tl; dr - Ada ringkasan di akhir dan judul di jawaban untuk memudahkan menemukan bagian yang relevan. Meskipun demikian, membaca semuanya disarankan karena memberikan latar belakang yang berguna untuk memahami mengapa hal itu membuat melihat bagaimana penerapannya dalam keadaan yang berbeda lebih mudah.
Tentang Kebijakan Asal yang Sama
Ini adalah Kebijakan Asal yang Sama . Ini adalah fitur keamanan yang diterapkan oleh browser.
Kasus khusus Anda menunjukkan bagaimana ini diimplementasikan untuk XMLHttpRequest (dan Anda akan mendapatkan hasil yang identik jika Anda menggunakan fetch), tetapi itu juga berlaku untuk hal-hal lain (seperti gambar yang dimuat ke
<canvas>
atau dokumen yang dimuat ke dalam<iframe>
), hanya dengan implementasi yang sedikit berbeda.(Anehnya, ini juga berlaku untuk font CSS, tetapi itu karena pengecoran yang ditemukan bersikeras pada DRM dan bukan untuk masalah keamanan yang biasanya dicakup oleh Kebijakan Asal yang Sama).
Skenario standar yang menunjukkan perlunya SOP dapat ditunjukkan dengan tiga karakter :
https://www.[website].com/
dalam contoh Anda)http://localhost:4300
dalam contoh Anda)Alice masuk ke situs Bob dan memiliki beberapa data rahasia di sana. Mungkin itu intranet perusahaan (hanya dapat diakses oleh browser di LAN), atau perbankan online-nya (hanya dapat diakses dengan cookie yang Anda dapatkan setelah memasukkan nama pengguna dan kata sandi).
Alice mengunjungi situs Mallory yang memiliki beberapa JavaScript yang menyebabkan browser Alice membuat permintaan HTTP ke situs Bob (dari alamat IP-nya dengan cookie-nya, dll). Ini bisa sesederhana menggunakan
XMLHttpRequest
dan membacaresponseText
.Kebijakan Asal yang Sama pada browser mencegah JavaScript membaca data yang dikembalikan oleh situs web Bob (yang tidak ingin diakses oleh Bob dan Alice oleh Mallory). (Perhatikan bahwa Anda dapat, misalnya, menampilkan gambar menggunakan
<img>
elemen di seluruh sumber karena konten gambar tidak diekspos ke JavaScript (atau Mallory)… kecuali Anda memasukkan kanvas ke dalam campuran yang dalam hal ini Anda akan menghasilkan sumber yang sama kesalahan pelanggaran).Mengapa Kebijakan Asal yang Sama berlaku saat menurut Anda tidak seharusnya
Untuk setiap URL tertentu mungkin saja SOP tidak diperlukan. Beberapa skenario umum di mana hal ini terjadi adalah:
… Tetapi browser tidak memiliki cara untuk mengetahui apakah salah satu hal di atas benar, jadi kepercayaan tidak otomatis dan SOP diterapkan. Izin harus diberikan secara eksplisit sebelum browser memberikan data yang diberikan ke situs web lain.
Mengapa Kebijakan Asal yang Sama hanya berlaku untuk JavaScript di halaman web
Ekstensi browser
*
, tab Jaringan di alat pengembang browser dan aplikasi seperti Postman adalah perangkat lunak yang diinstal. Mereka tidak meneruskan data dari satu situs web ke JavaScript milik situs web lain hanya karena Anda mengunjungi situs web berbeda tersebut . Menginstal perangkat lunak biasanya membutuhkan pilihan yang lebih sadar.Tidak ada pihak ketiga (Mallory) yang dianggap berisiko.
*
Ekstensi browser perlu ditulis dengan hati-hati untuk menghindari masalah lintas sumber. Lihat dokumentasi Chrome misalnya .Mengapa Anda dapat menampilkan data di halaman tanpa membacanya dengan JS
Ada beberapa keadaan di mana situs Mallory dapat menyebabkan browser mengambil data dari pihak ketiga dan menampilkannya (misalnya dengan menambahkan
<img>
elemen untuk menampilkan gambar). JavaScript Mallory tidak mungkin membaca data dalam sumber daya itu, hanya browser Alice dan server Bob yang dapat melakukannya, jadi itu masih aman.CORS
The
Access-Control-Allow-Origin
HTTP respon header yang dimaksud dalam pesan kesalahan adalah bagian dari CORS standar yang memungkinkan Bob secara eksplisit memberikan izin ke situs Mallory untuk akses data melalui browser Alice.Implementasi dasar hanya akan mencakup:
… Di tajuk tanggapan untuk mengizinkan situs web mana pun membaca data.
… Hanya akan mengizinkan situs tertentu untuk mengaksesnya, dan Bob dapat secara dinamis menghasilkan itu berdasarkan header
Origin
permintaan untuk mengizinkan beberapa, tetapi tidak semua, situs untuk mengaksesnya.Secara spesifik bagaimana Bob menyetel header respons tersebut bergantung pada server HTTP Bob dan / atau bahasa pemrograman sisi server. Ada kumpulan panduan untuk berbagai konfigurasi umum yang mungkin bisa membantu.
NB: Beberapa permintaan rumit dan mengirim permintaan OPTIONS pra - penerbangan yang harus ditanggapi oleh server sebelum browser mengirim permintaan GET / POST / PUT / Apapun yang ingin dibuat JS. Penerapan CORS yang hanya menambahkan
Access-Control-Allow-Origin
ke URL tertentu sering kali tersandung oleh hal ini.Memberikan izin melalui CORS adalah sesuatu yang hanya akan dilakukan Bob jika:
Tapi aku bukan Bob!
Tidak ada mekanisme standar bagi Mallory untuk menambahkan tajuk ini karena harus berasal dari situs web Bob, yang tidak dikontrolnya.
Jika Bob menjalankan API publik, mungkin ada mekanisme untuk mengaktifkan CORS (mungkin dengan memformat permintaan dengan cara tertentu, atau opsi konfigurasi setelah masuk ke situs Portal Pengembang untuk situs Bob). Ini harus menjadi mekanisme yang diterapkan oleh Bob. Mallory dapat membaca dokumentasi di situs Bob untuk melihat apakah ada sesuatu yang tersedia, atau dia dapat berbicara dengan Bob dan memintanya untuk menerapkan CORS.
Pesan kesalahan yang menyebutkan "Respon untuk preflight"
Beberapa permintaan lintas asal sudah ditentukan sebelumnya .
Ini terjadi ketika (secara kasar) Anda mencoba membuat permintaan lintas sumber yang:
enctype
).Jika Anda benar melakukan sesuatu yang membutuhkan penerbangan sebelumnya
Dalam kasus ini , sisa dari jawaban ini masih berlaku tetapi Anda juga perlu memastikan bahwa server dapat mendengarkan permintaan preflight (yang akan
OPTIONS
(dan bukanGET
,POST
atau apa pun yang Anda coba kirim) dan menanggapinya dengan benar.Access-Control-Allow-Origin
header tetapi jugaAccess-Control-Allow-Methods
danAccess-Control-Allow-Headers
untuk mengizinkan metode atau header HTTP spesifik Anda.Jika Anda memicu preflight karena kesalahan
Terkadang orang membuat kesalahan saat mencoba membuat permintaan Ajax, dan terkadang hal ini memicu kebutuhan akan penerbangan sebelumnya. Jika API dirancang untuk mengizinkan permintaan lintas sumber, tetapi tidak memerlukan apa pun yang memerlukan penerbangan sebelumnya, hal ini dapat merusak akses.
Kesalahan umum yang memicu hal ini meliputi:
Access-Control-Allow-Origin
dan header tanggapan CORS lainnya atas permintaan tersebut. Ini bukan milik atas permintaan, jangan melakukan apa pun yang membantu (apa gunanya sistem perizinan di mana Anda dapat memberikan izin kepada diri sendiri?), Dan harus muncul hanya pada tanggapan.Content-Type: application/json
header pada permintaan GET yang tidak memiliki isi permintaan untuk mendeskripsikan konten (biasanya ketika penulis bingungContent-Type
danAccept
).Dalam salah satu kasus ini, menghapus header permintaan tambahan sering kali cukup untuk menghindari perlunya preflight (yang akan menyelesaikan masalah saat berkomunikasi dengan API yang mendukung permintaan sederhana tetapi bukan permintaan preflighted).
Tanggapan buram
Terkadang Anda perlu membuat permintaan HTTP, tetapi Anda tidak perlu membaca responsnya. misalnya jika Anda memposting pesan log ke server untuk direkam.
Jika Anda menggunakan satu
fetch
API (bukanXMLHttpRequest
), maka Anda bisa mengkonfigurasinya untuk tidak mencoba untuk menggunakan CORS.Perhatikan bahwa ini tidak akan membiarkan Anda melakukan apa pun yang Anda perlukan untuk dilakukan CORS. Anda tidak akan dapat membaca tanggapannya. Anda tidak akan dapat membuat permintaan yang membutuhkan penerbangan sebelumnya.
Ini akan memungkinkan Anda membuat permintaan sederhana, tidak melihat respons, dan tidak mengisi Konsol Pengembang dengan pesan kesalahan.
Bagaimana melakukannya dijelaskan oleh pesan kesalahan Chrome yang diberikan saat Anda membuat permintaan menggunakan
fetch
dan tidak mendapatkan izin untuk melihat tanggapan dengan CORS:Jadi:
Alternatif untuk CORS
JSONP
Bob juga dapat memberikan data menggunakan peretasan seperti JSONP yang merupakan cara orang melakukan Ajax lintas asal sebelum CORS datang.
Ia bekerja dengan menyajikan data dalam bentuk program JavaScript yang memasukkan data ke halaman Mallory.
Itu mengharuskan Mallory mempercayai Bob untuk tidak memberikan kode berbahaya.
Perhatikan tema umum: Situs yang menyediakan data harus memberi tahu browser bahwa tidak masalah bagi situs pihak ketiga untuk mengakses data yang dikirim ke browser.
Karena JSONP bekerja dengan menambahkan
<script>
elemen untuk memuat data dalam bentuk program JavaScript yang memanggil fungsi yang sudah ada di halaman, mencoba menggunakan teknik JSONP pada URL yang menampilkan JSON akan gagal - biasanya dengan error CORB - karena JSON bukan JavaScript.Pindahkan dua sumber daya ke satu Asal
Jika dokumen HTML tempat JS berjalan dan URL yang diminta berada pada asal yang sama (berbagi skema, nama host, dan port yang sama) maka Kebijakan Asal yang Sama memberikan izin secara default. CORS tidak diperlukan.
Proxy
Mallory dapat menggunakan kode sisi server untuk mengambil data (yang kemudian dapat diteruskan dari servernya ke browser Alice melalui HTTP seperti biasa).
Ini akan:
Kode sisi server tersebut dapat ditulis & dihosting oleh pihak ketiga (seperti CORS Anywhere). Perhatikan implikasi privasi dari ini: Pihak ketiga dapat memantau siapa yang membuat proxy apa di server mereka.
Bob tidak perlu memberikan izin apa pun agar hal itu terjadi.
Tidak ada implikasi keamanan di sini karena itu hanya antara Mallory dan Bob. Tidak ada cara bagi Bob untuk berpikir bahwa Mallory adalah Alice dan memberikan Mallory data yang harus dirahasiakan antara Alice dan Bob.
Akibatnya, Mallory hanya bisa menggunakan teknik ini untuk membaca data publik .
Namun, perhatikan bahwa mengambil konten dari situs web orang lain dan menampilkannya sendiri mungkin merupakan pelanggaran hak cipta dan membuat Anda terbuka untuk tindakan hukum.
Menulis sesuatu selain aplikasi web
Seperti disebutkan di bagian "Mengapa Kebijakan Asal yang Sama hanya berlaku untuk JavaScript di halaman web", Anda dapat menghindari SOP dengan tidak menulis JavaScript di halaman web.
Itu tidak berarti Anda tidak dapat terus menggunakan JavaScript dan HTML, tetapi Anda dapat mendistribusikannya menggunakan mekanisme lain, seperti Node-WebKit atau PhoneGap.
Ekstensi browser
Ekstensi browser mungkin saja memasukkan header CORS dalam tanggapan sebelum Kebijakan Asal yang Sama diterapkan.
Ini dapat berguna untuk pengembangan, tetapi tidak praktis untuk situs produksi (tidak masuk akal meminta setiap pengguna situs Anda untuk memasang ekstensi browser yang menonaktifkan fitur keamanan browser mereka).
Mereka juga cenderung bekerja hanya dengan permintaan sederhana (gagal saat menangani permintaan OPTIONS preflight).
Memiliki lingkungan pengembangan yang tepat dengan server pengembangan lokal biasanya merupakan pendekatan yang lebih baik.
Risiko keamanan lainnya
Perhatikan bahwa SOP / CORS tidak mengurangi serangan XSS , CSRF , atau SQL Injection yang perlu ditangani secara independen.
Ringkasan
sumber
Server target harus mengizinkan permintaan lintas sumber. Untuk mengizinkannya melalui express, cukup tangani permintaan opsi http:
sumber
Karena ini tidak disebutkan dalam jawaban yang diterima.
Anda dapat menggunakan Permintaan Sederhana .
Untuk melakukan 'Permintaan Sederhana', permintaan harus memenuhi beberapa ketentuan. Misalnya hanya mengizinkan
POST
,GET
danHEAD
metode, serta hanya mengizinkan beberapa Header tertentu (Anda dapat menemukan semua ketentuan di sini ).Jika kode klien Anda tidak secara eksplisit mengatur Header yang terpengaruh (misalnya, "Terima") dengan nilai perbaikan dalam permintaan, mungkin terjadi bahwa beberapa klien menyetel Header ini secara otomatis dengan beberapa nilai "non-standar" yang menyebabkan server tidak menerimanya sebagai Permintaan Sederhana - yang akan memberi Anda kesalahan CORS.
sumber
Ini terjadi karena kesalahan CORS. CORS adalah singkatan dari Cross Origin Resource Sharing. Dengan kata sederhana, kesalahan ini terjadi ketika kami mencoba mengakses domain / sumber daya dari domain lain.
Baca Selengkapnya tentang itu di sini: Kesalahan CORS dengan jquery
Untuk memperbaikinya, jika Anda memiliki akses ke domain lain, Anda harus mengizinkan Access-Control-Allow-Origin di server. Ini dapat ditambahkan di header. Anda dapat mengaktifkan ini untuk semua permintaan / domain atau domain tertentu.
Cara membuat permintaan posting berbagi sumber daya lintas sumber (CORS) berfungsi
Tautan ini mungkin membantu
sumber
Masalah CORS ini tidak dijelaskan lebih lanjut (untuk penyebab lain).
Saya mengalami masalah ini saat ini karena alasan yang berbeda. Bagian depan saya juga mengembalikan kesalahan header 'Access-Control-Allow-Origin'.
Hanya saja saya telah mengarahkan URL yang salah sehingga tajuk ini tidak tercermin dengan benar (di mana saya terus menganggapnya demikian). localhost (front end) -> panggilan ke http tidak aman (seharusnya https), pastikan titik akhir API dari ujung depan mengarah ke protokol yang benar.
sumber
Saya mendapat kesalahan yang sama di konsol Chrome.
Masalah saya adalah, saya mencoba untuk pergi ke situs menggunakan
http://
bukanhttps://
. Jadi tidak ada yang perlu diperbaiki, hanya harus pergi ke situs yang sama menggunakanhttps
.sumber
Permintaan "Dapatkan" dengan menambahkan header yang diubah menjadi permintaan "Opsi". Jadi masalah kebijakan Cors terjadi. Anda harus menerapkan permintaan "Opsi" ke server Anda.
sumber
Anda harus mengaktifkan CORS agar berfungsi.
sumber