Ebben a cikkben megtudjuk, hogyan engedélyezhetjük a CORS-t (Cross-Origin Resource Sharing) HTTPOnly cookie-val a hozzáférési jogkivonataink védelme érdekében.
Manapság a háttérkiszolgálókat és a frontend klienseket különböző tartományokon telepítik. Ezért a szervernek engedélyeznie kell a CORS-t, hogy az ügyfelek kommunikáljanak a szerverrel a böngészőkön.
Ezenkívül a kiszolgálók állapot nélküli hitelesítést valósítanak meg a jobb méretezhetőség érdekében. A tokenek tárolása és karbantartása a kliens oldalon történik, de nem a szerver oldalon, mint a munkamenet. A biztonság érdekében jobb, ha a tokeneket HTTPOnly cookie-kban tárolja.
Tartalomjegyzék
Miért vannak letiltva a Cross-Origin kérelmek?
Tegyük fel, hogy a frontend alkalmazásunk a https://app.etoppc.com.com címen van telepítve. A https://app.etoppc.com.com címen betöltött szkript csak azonos eredetű erőforrásokat kérhet.
Amikor megpróbálunk több eredetű kérelmet küldeni egy másik tartományra https://api.etoppc.com.com vagy másik portra https://app.etoppc.com.com:3000 vagy más sémára http://app.etoppc.com.com, a A kereszt-eredetű kérelmet a böngésző blokkolja.
De miért lehet ugyanazt a böngésző által blokkolt kérést elküldeni bármely háttérkiszolgálóról curl kéréssel vagy olyan eszközökkel, mint a postás CORS probléma nélkül. Valójában a biztonság célja, hogy megvédje a felhasználókat az olyan támadásoktól, mint a CSRF (Cross-Site Request Forgery).
Vegyünk egy példát, tegyük fel, ha bármelyik felhasználó bejelentkezett a saját PayPal-fiókjába a böngészőjében. Ha egy másik, malicious.com domainre betöltött szkriptből tudunk küldeni egy kereszteredetű kérelmet a paypal.com-nak CORS-hiba/blokkolás nélkül, például elküldjük az azonos eredetű kérést.
A támadók könnyen elküldhetik rosszindulatú oldalukat https://malicious.com/transfer-money-to-attacker-account-from-user-paypal-account, ha rövid URL-re konvertálják a tényleges URL elrejtése érdekében. Amikor a felhasználó rákattint egy rosszindulatú hivatkozásra, a malicious.com tartományba betöltött szkript egy kereszt-eredetű kérelmet küld a PayPalnak, hogy utalja át a felhasználói összeget a támadó PayPal-számlájára. Minden felhasználó, aki bejelentkezett PayPal-fiókjába, és rákattintott erre a rosszindulatú linkre, elveszíti a pénzét. PayPal fiók felhasználói ismerete nélkül bárki könnyedén lophat pénzt.
A fenti okból kifolyólag a böngészők blokkolják az összes több eredetű kérést.
Mi az a CORS (cross-Origin Resource Sharing)?
A CORS egy fejléc alapú biztonsági mechanizmus, amelyet a kiszolgáló arra használ, hogy utasítsa a böngészőt, hogy küldjön több eredetű kérést megbízható tartományokból.
A CORS-fejlécekkel engedélyezett szerver a böngészők által blokkolt, több eredetre vonatkozó kérések elkerülésére szolgál.
Hogyan működik a CORS?
Mivel a szerver már meghatározta a megbízható tartományát a CORS-konfigurációjában. Amikor kérést küldünk a szervernek, a válasz a fejlécében közli a böngészővel, hogy a kért tartomány megbízható-e vagy sem.
Kétféle CORS-kérelem létezik:
- Egyszerű kérés
- Repülés előtti kérelem
Egyszerű kérés:
- A böngésző elküldi a kérést egy eredethatárokon átnyúló tartománynak, amelynek eredete (https://app.etoppc.com.com).
- A szerver visszaküldi a megfelelő választ engedélyezett metódusokkal és engedélyezett eredetekkel.
- A kérés beérkezése után a böngésző ellenőrzi, hogy az elküldött eredet fejléc értéke (https://app.etoppc.com.com) és a kapott access-control-allow-origin érték (https://app.etoppc.com.com) megegyezik-e, ill. helyettesítő karakter
. Ellenkező esetben CORS hibát fog kiadni.
- Repülés előtti kérés:
- A több eredetű kérés egyéni kérési paraméterétől függően, például metódusok (PUT, DELETE) vagy egyéni fejlécek vagy eltérő tartalomtípus stb. vagy nem.
Miután megkapta a választ (állapotkód: 204, ami azt jelenti, hogy nincs tartalom), a böngésző ellenőrzi a hozzáférés-vezérlés engedélyezése paramétereket az aktuális kéréshez. Ha a kérés paramétereit a szerver engedélyezi. A tényleges, több származású kérés elküldve és fogadva
Ha access-control-allow-origin: *, akkor a válasz minden eredetre engedélyezett. De nem biztonságos, hacsak nincs rá szüksége.
Hogyan lehet engedélyezni a CORS-t?
A CORS bármely tartományban engedélyezéséhez engedélyezze a CORS-fejléceket, amelyek lehetővé teszik az eredetet, metódusokat, egyéni fejléceket, hitelesítési adatokat stb.
- A böngésző beolvassa a CORS fejlécet a szerverről, és csak a kérésparaméterek ellenőrzése után engedélyezi a klienstől érkező tényleges kéréseket.
- Access-Control-Allow-Origin: Pontos tartományok (https://app.geekflate.com, https://lab.etoppc.com.com) vagy helyettesítő karakterek megadása
- Access-Control-Allow-Methods: A HTTP metódusok (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) engedélyezése, amelyekre csak nekünk van szükségünk.
- Access-Control-Allow-Headers: Csak meghatározott fejlécek engedélyezése (engedélyezés, csrf-token)
- Access-Control-Allow-Credentials: logikai érték, amely lehetővé teszi a kereszt-eredetű hitelesítő adatokat (cookie-k, engedélyezési fejléc).
Access-Control-Max-Age: utasítja a böngészőt, hogy egy ideig gyorsítótárba helyezze a vizsgálat előtti választ.
Access-Control-Expose-Headers: Adja meg az ügyféloldali szkripttel elérhető fejléceket.
A CORS engedélyezéséhez az apache-ban és az Nginx webszerverben kövesse ezt az oktatóanyagot.
const express = require('express'); const app = express() app.get('/users', function (req, res, next) { res.json({msg: 'user get'}) }); app.post('/users', function (req, res, next) { res.json({msg: 'user create'}) }); app.put('/users', function (req, res, next) { res.json({msg: 'User update'}) }); app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') })
A CORS engedélyezése az ExpressJS-ben
Vegyünk egy példát az ExpressJS alkalmazásra CORS nélkül:
npm install cors
A fenti példában engedélyeztük a felhasználók API-végpontját a POST, PUT, GET metódusokhoz, de nem a DELETE metódushoz.
A CORS egyszerű engedélyezéséhez az ExpressJS alkalmazásban telepítheti a cors-t
app.use(cors({ origin: '*' }));
Access-Control-Allow-Origin
app.use(cors({ origin: 'https://app.etoppc.com.com' }));
A CORS engedélyezése az összes domainhez
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ] }));
A CORS engedélyezése egyetlen tartományhoz
Ha engedélyezni szeretné a CORS-t az eredethez: https://app.etoppc.com.com és https://lab.etoppc.com.com
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'] }));
Access-Control-Allow-Methods
Ha minden metódushoz szeretné engedélyezni a CORS-t, hagyja ki ezt a beállítást az ExpressJS CORS-moduljában. De bizonyos módszerek engedélyezéséhez (GET, POST, PUT).
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'] }));
Access-Control-Allow-Headers
Az alapértelmezetttől eltérő fejlécek tényleges kérésekkel való küldésének engedélyezésére szolgál.
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'], credentials: true }));
Access-Control-Allow-Credentials
Hagyja ki ezt, ha nem szeretné megmondani a böngészőnek, hogy kérésre engedélyezze a hitelesítő adatokat, még akkor is, ha a withCredentials értéke igaz.
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'], credentials: true, maxAge: 600 }));
Access-Control-Max-Age
A böngésző ösztönzése arra, hogy a gyorsítótárban tárolja a vizsgálat előtti válaszinformációkat egy meghatározott másodpercig. Hagyja ki ezt, ha nem szeretné gyorsítótárba menteni a választ.
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'], credentials: true, maxAge: 600, exposedHeaders: ['Content-Range', 'X-Content-Range'] }));
A gyorsítótárazott elővizsgálati válasz 10 percig elérhető lesz a böngészőben.
app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'], credentials: true, maxAge: 600, exposedHeaders: ['*', 'Authorization', ] }));
Access-Control-Expose-Headers
Ha feltesszük a helyettesítő karaktert
Az exponált fejlécekben nem teszi közzé az engedélyezési fejlécet. Tehát explicit módon kell kitennünk, mint alább
A fentiek megjelenítik az összes fejlécet és az engedélyezési fejlécet is.
- Mi az a HTTP cookie?
- A cookie egy kis adat, amelyet a szerver elküld a kliens böngészőjének. Későbbi kérések esetén a böngésző minden kérésnél elküldi az ugyanahhoz a domainhez kapcsolódó összes cookie-t.
- A cookie-nak megvan a maga attribútuma, amely megadható, hogy a süti másképp működjön, ahogyan szükségünk van rá.
- Név A cookie neve.
- érték: a cookie-nak a cookie-névhez tartozó adatai
- Domain: a cookie-kat csak a meghatározott domainre küldjük
- Elérési út: csak a meghatározott URL előtag elérési útja után küldött cookie-k. Tegyük fel, hogy a cookie elérési útját úgy határoztuk meg, hogy path=’admin/’. A cookie-kat nem a https://etoppc.com.com/expire/ URL-hez küldik, hanem a https://etoppc.com.com/admin/ URL előtaggal
- Max-Age/Expires (szám másodpercben): Mikor jár le a cookie. A süti élettartama érvényteleníti a cookie-t a megadott idő elteltével. [Strict, Lax, None]HTTPOnly (logikai): A háttérkiszolgáló elérheti a HTTPOnly cookie-t, de nem fér hozzá az ügyféloldali szkripthez, ha igaz. Biztonságos (logikai érték): Csak SSL/TLS tartományon keresztül küldött cookie-k igazak.sameSite(string
): A webhelyek közötti kérésekre küldött cookie-k engedélyezésére/korlátozására szolgál. Ha többet szeretne megtudni a cookie-król a sameSite, lásd
MDN
. Három lehetőséget fogad el: Szigorú, Lax, Nincs. A cookie-k biztonságos értéke igazra van állítva a cookie-konfigurációhoz sameSite=Nincs.
Miért HTTPOnly cookie a tokenekhez?
A kiszolgálóról küldött hozzáférési jogkivonat ügyféloldali tárhelyen, például helyi tárolóban, indexelt DB-ben és cookie-ban (HTTOnly nincs igazra állítva) sebezhetőbb az XSS-támadásokkal szemben. Tegyük fel, ha valamelyik oldala gyenge XSS-támadásra. A támadók visszaélhetnek a böngészőben tárolt felhasználói tokenekkel.
A HTTPOnly cookie-kat csak a szerver/háttér állítja be/kapja meg, de nem a kliens oldalon.
- Az ügyféloldali szkript korlátozva van a HTTPonly cookie elérésére. Tehát a HTTPOnly cookie-k nem sebezhetők az XSS-támadásokkal szemben, és biztonságosabbak. Mert csak a szerver érheti el.
- A HTTPOnly cookie engedélyezése a CORS-kompatibilis háttérrendszerben
- A Cookie CORS-ben engedélyezéséhez az alábbi konfigurációra van szükség az alkalmazásban/szerverben.
- Állítsa igazra az Access-Control-Allow-Credentials fejlécet.
Az Access-Control-Allow-Origin és a Access-Control-Allow-Headers nem lehet helyettesítő karakter.
const express = require('express'); const app = express(); const cors = require('cors'); app.use(cors({ origin: [ 'https://app.geekflare.com', 'https://lab.geekflare.com' ], methods: ['GET', 'PUT', 'POST'], allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'], credentials: true, maxAge: 600, exposedHeaders: ['*', 'Authorization' ] })); app.post('/login', function (req, res, next) { res.cookie('access_token', access_token, { expires: new Date(Date.now() + (3600 * 1000 * 24 * 180 * 1)), //second min hour days year secure: true, // set to true if your using https or samesite is none httpOnly: true, // backend only sameSite: 'none' // set to none for cross-request }); res.json({ msg: 'Login Successfully', access_token }); }); app.listen(80, function () { console.log('CORS-enabled web server listening on port 80') });
.
A cookie sameSite attribútuma None legyen.
A sameSite érték none beállításához állítsa a biztonságos értéket igazra: Engedélyezze az SSL/TLS-tanúsítvánnyal rendelkező háttérrendszer működését a tartománynévben.
Lássunk egy példakódot, amely a bejelentkezési adatok ellenőrzése után hozzáférési tokent állít be a HTTPOnly cookie-ban.
A CORS és a HTTPOnly cookie-kat úgy konfigurálhatja, hogy végrehajtja a fenti négy lépést a háttérnyelven és a webszerveren.
var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://api.etoppc.com.com/user', true); xhr.withCredentials = true; xhr.send(null);
Kövesse ezt az oktatóanyagot az apache és az Nginx számára a CORS engedélyezéséhez a fenti lépések végrehajtásával.
fetch('http://api.etoppc.com.com/user', { credentials: 'include' });
a Cross-Origin kérés hitelesítő adataival
$.ajax({ url: 'http://api.etoppc.com.com/user', xhrFields: { withCredentials: true } });
A hitelesítési adatok (cookie, engedélyezés) alapértelmezés szerint azonos eredetű kéréssel lettek elküldve. Cross-origin esetén a withCredentials értéket true értékre kell adnunk.
axios.defaults.withCredentials = true
XMLHttpRequest API
API lekérése
JQuery AjaxAxiosKövetkeztetés Remélem, a fenti cikk segít megérteni, hogyan működik a CORS, és engedélyezi a CORS-t a több eredetű kérelmek számára a szerveren. Miért biztonságos a cookie-k tárolása a HTTPOnly-ban, és hogyan használhatók az ügyfelekben a több eredetű kérésekhez használt hitelesítő adatok.