Saya mempunyai proses Grunt yang memulakan contoh pelayan express.js. Ini semua berfungsi dengan baik sehingga tadi, tetapi kini ia mula menyiarkan halaman kosong dan memaparkan perkara berikut dalam log ralat dalam konsol pembangun Chrome (versi terkini):
XMLHttpRequest tidak boleh memuatkan https://www.example.com/ Tiada pengepala 'Access-Control-Allow-Origin' pada sumber yang diminta. Oleh itu, akses daripada 'http://localhost:4300' tidak dibenarkan.
Apakah yang menghalang saya daripada mengakses halaman ini?
Pelayan sasaran mesti membenarkan permintaan merentas domain. Untuk membolehkannya melalui ekspres, hanya kendalikan permintaan pilihan http:
tl;dr — Apabila anda ingin membaca data, (kebanyakannya) menggunakan JS sisi klien, daripada pelayan lain anda memerlukan pelayan dengan data untuk memberikan kebenaran yang jelas kepada kod yang mahukan data. Terdapat ringkasan di hujung dan tajuk dalam jawapan untuk memudahkan mencari bahagian yang berkaitan. Membaca segala-galanya adalah disyorkan walaupun kerana ia menyediakan latar belakang yang berguna untuk memahami
mengapayang menjadikan melihat bagaimana bagaimana terpakai dalam keadaan yang berbeza lebih mudah. Mengenai Dasar Asal Yang Sama
Ini adalah
Dasar Asal Yang Sama. Ia adalah ciri keselamatan yang dilaksanakan oleh pelayar. Kes tertentu anda menunjukkan cara ia dilaksanakan untuk XMLHttpRequest (dan anda akan mendapat hasil yang sama jika anda menggunakan fetch), tetapi ia juga digunakan untuk perkara lain (seperti imej yang dimuatkan ke
), hanya dengan pelaksanaan yang sedikit berbeza .<canvas>
or documents loaded into an<iframe>
Senario standard yang menunjukkan keperluan untuk SOP boleh ditunjukkan dengan:
Alice ialah seorang yang mempunyai pelayar webhttps://www.example.com/
Mallory menjalankan tapak web (http://localhost:4300
Alice melawat tapak web Mallory yang mempunyai beberapa JavaScript yang menyebabkan penyemak imbas Alice membuat permintaan HTTP ke tapak web Bob (dari alamat IPnya dengan kukinya, dll). Ini boleh jadi semudah menggunakan
.XMLHttpRequest
and reading theresponseText
Dasar Asal Yang Sama penyemak imbas menghalang JavaScript daripada membaca data yang dikembalikan oleh tapak web Bob (yang Bob dan Alice tidak mahu Mallory akses). (Perhatikan bahawa anda boleh, sebagai contoh, memaparkan imej menggunakan elemenakan
Mengapa Polisi Asal yang Sama terpakai apabila anda rasa ia tidak sepatutnya<img>
menjana ralat pelanggaran asal yang sama).Untuk mana-mana URL yang diberikan kemungkinan SOP tidak diperlukan. Beberapa senario biasa yang berlaku adalah:
… tetapi penyemak imbas tidak mempunyai cara untuk mengetahui sama ada salah satu di atas adalah benar, jadi kepercayaan tidak automatik dan SOP digunakan. Kebenaran perlu diberikan secara jelas sebelum penyemak imbas akan memberikan data yang telah diterima daripada Bob ke beberapa tapak web lain.
Mengapa Dasar Asal yang Sama digunakan pada JavaScript dalam halaman web tetapi sedikit lagi
Di luar laman web
Sambungan penyemak imbas
*
, tab Rangkaian dalam alat pembangun penyemak imbas dan aplikasi seperti Postman adalah perisian yang dipasang. Mereka tidak menghantar data dari satu tapak web ke JavaScript milik tapak web yang berbeza hanya kerana anda melawati tapak web yang berbeza itu. Memasang perisian biasanya memerlukan pilihan yang lebih sedar.Tiada pihak ketiga (Mallory) yang dianggap sebagai risiko.
*
Sambungan penyemak imbas perlu ditulis dengan teliti untuk mengelakkan isu silang asal. Lihat dokumentasi Chrome sebagai contoh.Di dalam halaman web
Kebanyakan masa, tidak terdapat banyak kebocoran maklumat apabila hanya menunjukkan sesuatu pada halaman web.
Jika anda menggunakan atribut
<img>
element to load an image, then it gets shown on the page, but very little information is exposed to Mallory. JavaScript can't read the image (unless you use acrossOrigin
untuk mendayakan kebenaran permintaan secara eksplisit dengan CORS) dan kemudian menyalinnya ke pelayannya.Maksudnya, sesetengah maklumat benar-benar bocor, untuk memetik Domenic Denicola (dari Google):
Inilah sebabnya anda memerlukan kebenaran CORS untuk memuatkan fon merentas asal.
Mengapa anda boleh memaparkan data pada halaman tanpa membacanya dengan JS
Terdapat beberapa keadaan di mana tapak Mallory boleh menyebabkan penyemak imbas mengambil data daripada pihak ketiga dan memaparkannya (cth. dengan menambahkan elemen
<img>
untuk memaparkan imej). JavaScript Mallory tidak mungkin membaca data dalam sumber itu, hanya penyemak imbas Alice dan pelayan Bob boleh melakukannya, jadi ia masih selamat.CORS
Pengepala
Access-Control-Allow-Origin
HTTP respon yang dirujuk dalam mesej ralat adalah sebahagian daripada standard CORS yang membolehkan Bob memberikan kebenaran secara jelas kepada tapak Mallory untuk mengakses data melalui penyemak imbas Alice.Pelaksanaan asas hanya akan merangkumi:
… dalam pengepala respons untuk membenarkan mana-mana tapak web membaca data.
… akan membenarkan hanya tapak tertentu mengaksesnya dan Bob boleh menjananya secara dinamik berdasarkan pengepala
Origin
permintaan untuk membenarkan berbilang, tetapi bukan semua, tapak mengaksesnya.Spesifik cara Bob menetapkan pengepala respons itu bergantung pada pelayan HTTP Bob dan/atau bahasa pengaturcaraan sebelah pelayan. Pengguna Node.js/Express.js harus menggunakan perisian tengah CORS yang didokumentasikan dengan baik. Pengguna platform lain harus melihat koleksi panduan ini untuk pelbagai konfigurasi biasa yang mungkin membantu.
NB: Sesetengah permintaan adalah rumit dan hantar permintaan preflight OPTIONS yang pelayan perlu balas sebelum penyemak imbas akan menghantar GET/POST/PUT/Apa sahaja permintaan yang JS ingin buat. Pelaksanaan CORS yang hanya menambah
Access-Control-Allow-Origin
pada URL tertentu sering tersandung oleh perkara ini.Jelas sekali memberikan kebenaran melalui CORS adalah sesuatu yang Bob hanya akan lakukan jika sama ada:
Bagaimana cara menambah pengepala ini?
Ia bergantung pada persekitaran bahagian pelayan anda.
Jika anda boleh, gunakan perpustakaan yang direka untuk mengendalikan CORS kerana ia akan memberikan anda pilihan mudah dan bukannya perlu berurusan dengan semuanya secara manual.
Enable-Cors.org mempunyai senarai dokumentasi untuk platform dan rangka kerja tertentu yang mungkin berguna untuk anda.
Tetapi saya bukan Bob!
Tiada mekanisme standard untuk Mallory menambah pengepala ini kerana ia mesti datang dari tapak web Bob, yang tidak dikawalnya.
Jika Bob menjalankan API awam maka mungkin terdapat mekanisme untuk menghidupkan CORS (mungkin dengan memformat permintaan dengan cara tertentu, atau pilihan konfigurasi selepas log masuk ke tapak Portal Pembangun untuk tapak Bob). Ini mesti menjadi mekanisme yang dilaksanakan oleh Bob. Mallory boleh membaca dokumentasi di tapak Bob untuk melihat sama ada sesuatu tersedia, atau dia boleh bercakap dengan Bob dan memintanya melaksanakan CORS.
Mesej ralat yang menyebut "Respons for preflight"
Sesetengah permintaan silang asal diterbangkan.
Ini berlaku apabila (secara kasarnya) anda cuba membuat permintaan silang asal bahawa:
enctype
atau beberapa pengepala permintaan lain).Jika anda melakukan sesuatu dengan betul yang memerlukan penerbangan awal
Dalam kes ini, selebihnya jawapan ini masih terpakai tetapi anda juga perlu memastikan pelayan boleh mendengar permintaan pra-penerbangan (yang akan menjadi
OPTIONS
(and notGET
,POST
, or whatever you were trying to send) and respond to it with the rightAccess-Control-Allow-Origin
header but alsoAccess-Control-Allow-Methods
andAccess-Control-Allow-Headers
untuk membenarkan kaedah atau pengepala HTTP khusus anda.Jika anda tersilap mencetuskan prapenerbangan
Kadang-kadang orang membuat kesilapan apabila cuba membina permintaan Ajax, dan kadangkala ini mencetuskan keperluan untuk penerbangan awal. Jika API direka bentuk untuk membenarkan permintaan silang asal tetapi tidak memerlukan apa-apa yang memerlukan prapenerbangan, maka ini boleh memecahkan akses.
Kesilapan biasa yang mencetuskan ini termasuk:
Access-Control-Allow-Origin
dan tajuk tindak balas CORS lain pada permintaan. Ini tidak sesuai dengan permintaan, jangan lakukan apa-apa yang membantu (apa gunanya sistem kebenaran yang membolehkan anda memberikan kebenaran kepada diri sendiri?), dan mesti dipaparkan hanya pada respons.Content-Type: application/json
header on a GET request that has no request body the content of which to describe (typically when the author confusesContent-Type
andAccept
).Dalam mana-mana kes ini, mengalih keluar pengepala permintaan tambahan selalunya mencukupi untuk mengelakkan keperluan untuk penerbangan awal (yang akan menyelesaikan masalah apabila berkomunikasi dengan API yang menyokong permintaan mudah tetapi bukan permintaan yang dimulakan).
Maklum balas legap (mod
no-cors
)Kadangkala anda perlu membuat permintaan HTTP, tetapi anda tidak perlu membaca jawapannya. cth. jika anda menghantar mesej log ke pelayan untuk dirakam.
Jika anda menggunakan the
fetch
API (rather thanXMLHttpRequest
), maka anda boleh mengkonfigurasinya untuk tidak cuba menggunakan CORS.Perhatikan bahawa ini tidak akan membenarkan anda melakukan apa sahaja yang anda perlukan CORS untuk lakukan. Anda tidak akan dapat membaca respons. Anda tidak akan dapat membuat permintaan yang memerlukan prapenerbangan.
Ini akan membolehkan anda membuat permintaan ringkas, tidak melihat respons dan tidak mengisi Konsol Pembangun dengan mesej ralat.
Cara melakukannya dijelaskan oleh mesej ralat Chrome yang diberikan apabila anda membuat permintaan menggunakan
fetch
dan tidak mendapat kebenaran untuk melihat respons dengan CORS:Oleh itu:
Alternatif kepada CORS
JSONP
Bob juga boleh memberikan data menggunakan penggodaman seperti JSONP iaitu cara orang melakukan Ajax silang asal sebelum CORS datang.
Ia berfungsi dengan membentangkan data dalam bentuk program JavaScript yang menyuntik data ke dalam halaman Mallory.
Ia memerlukan Mallory mempercayai Bob untuk tidak memberikan kod hasad.
Perhatikan tema biasa: Tapak yang menyediakan data perlu memberitahu penyemak imbas bahawa adalah OK untuk tapak pihak ketiga mengakses data yang dihantar ke penyemak imbas.
Memandangkan JSONP berfungsi dengan menambahkan elemen
<script>
untuk memuatkan data dalam bentuk program JavaScript yang memanggil fungsi yang sudah ada dalam halaman, percubaan untuk menggunakan teknik JSONP pada URL yang mengembalikan JSON akan gagal — biasanya dengan ralat CORB — kerana JSON bukan JavaScript.Alihkan dua sumber kepada satu Asal
Jika dokumen HTML JS dijalankan dan URL yang diminta adalah pada asal yang sama (berkongsi skema, nama hos dan port yang sama) maka Dasar Asal yang Sama memberikan kebenaran secara lalai. CORS tidak diperlukan.
Seorang Proksi
Mallory boleh menggunakan kod sisi pelayan untuk mengambil data (yang kemudiannya boleh dihantar dari pelayannya ke penyemak imbas Alice melalui HTTP seperti biasa).
Ia akan sama ada:
Kod sebelah pelayan itu boleh ditulis & dihoskan oleh pihak ketiga (seperti CORS Anywhere). Perhatikan implikasi privasi perkara ini: Pihak ketiga boleh memantau siapa yang proksi apa yang merentas pelayan mereka.
Bob tidak perlu memberikan sebarang kebenaran untuk itu berlaku.
Tiada implikasi keselamatan di sini kerana itu hanya antara Mallory dan Bob. Tidak ada cara untuk Bob menganggap Mallory adalah Alice dan memberikan Mallory data yang harus dirahsiakan antara Alice dan Bob.
Oleh itu, Mallory hanya boleh menggunakan teknik ini untuk membaca data awam.
Walau bagaimanapun, ambil perhatian bahawa mengambil kandungan daripada tapak web orang lain dan memaparkannya sendiri mungkin melanggar hak cipta dan membuka anda kepada tindakan undang-undang.
Menulis sesuatu selain apl web
Seperti yang dinyatakan dalam bahagian "Mengapa Dasar Asal Yang Sama hanya terpakai untuk JavaScript dalam halaman web", anda boleh mengelakkan SOP dengan tidak menulis JavaScript dalam halaman web.
Ini tidak bermakna anda tidak boleh terus menggunakan JavaScript dan HTML, tetapi anda boleh mengedarkannya menggunakan beberapa mekanisme lain, seperti Node-WebKit atau PhoneGap.
Sambungan penyemak imbas
Adalah kemungkinan untuk sambungan penyemak imbas menyuntik pengepala CORS dalam respons sebelum Dasar Asal Yang Sama digunakan.
Ini boleh berguna untuk pembangunan tetapi tidak praktikal untuk tapak pengeluaran (meminta setiap pengguna tapak anda memasang sambungan penyemak imbas yang melumpuhkan ciri keselamatan penyemak imbas mereka adalah tidak munasabah).
Mereka juga cenderung berfungsi hanya dengan permintaan mudah (gagal semasa mengendalikan permintaan OPTIONS prapenerbangan).
Mempunyai persekitaran pembangunan yang sesuai dengan pembangunan tempatan pelayan selalunya pendekatan yang lebih baik.
Risiko keselamatan lain
Perhatikan bahawa SOP / CORS tidak mengurangkan serangan XSS, CSRF, atau SQL Injection yang perlu dikendalikan secara bebas.
Ringkasan