Hogyan lehet engedélyezni a CORS-t HTTPOnly Cookie-val a biztonságos tokenhez?

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).

  Scala vs Java: különbségek és hasonlóságok

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).
  A Discord alkalmazás frissítése Linuxon

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

  Mindent a vállalkozások arcfelismeréséről

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.