Odkrijte skrivnosti CORS (Cross-Origin Resource Sharing) in se naučite, kako varno omogočiti zahteve med domenami v vaših spletnih aplikacijah. Ta celovit vodnik pokriva vse od osnov do naprednih konfiguracij, kar zagotavlja nemoteno in varno komunikacijo med različnimi izvori.
Razumevanje CORS: Celovit vodnik po souporabi virov med različnimi izvori
V današnjem povezanem spletu morajo aplikacije pogosto dostopati do virov iz različnih izvorov. Tu nastopi souporaba virov med različnimi izvori (CORS). CORS je ključen varnostni mehanizem, ki ureja, kako spletni brskalniki obravnavajo zahteve z enega izvora (domena, protokol in vrata) na drug izvor. Razumevanje CORS je bistveno za vsakega spletnega razvijalca, da lahko gradi varne in funkcionalne spletne aplikacije.
Kaj je politika istega izvora?
Preden se poglobimo v CORS, je pomembno razumeti politiko istega izvora (SOP). SOP je temeljni varnostni mehanizem, ki ga izvajajo spletni brskalniki. Njegov namen je preprečiti zlonamernim skriptam na eni spletni strani dostop do občutljivih podatkov na drugi spletni strani. Izvor je definiran s kombinacijo protokola (npr. HTTP ali HTTPS), domene (npr. example.com) in številke vrat (npr. 80 ali 443). Dva URL-ja se štejeta za isti izvor, če si delita isti protokol, domeno in vrata.
Primer:
http://example.com/app1
inhttp://example.com/app2
- Isti izvor (isti protokol, domena in vrata)https://example.com/app1
inhttp://example.com/app1
- Različen izvor (različen protokol)http://example.com:8080/app1
inhttp://example.com/app1
- Različen izvor (različna vrata)http://sub.example.com/app1
inhttp://example.com/app1
- Različen izvor (različna poddomena – šteje se za različno domeno)
SOP omejuje skriptam dostop do virov iz drugega izvora, razen če so za dovoljenje vzpostavljeni posebni ukrepi, kot je CORS.
Zakaj je CORS potreben?
Čeprav je politika istega izvora ključna za varnost, je lahko tudi omejujoča. Mnoge sodobne spletne aplikacije se zanašajo na pridobivanje podatkov z različnih strežnikov, kot so API-ji ali omrežja za dostavo vsebin (CDN). CORS zagotavlja nadzorovan način za sprostitev SOP in omogoča legitimne zahteve med različnimi izvori, hkrati pa ohranja varnost.
Predstavljajte si scenarij, kjer mora spletna aplikacija, gostovana na http://example.com
, pridobiti podatke s strežnika API, gostovanega na http://api.example.net
. Brez CORS bi brskalnik to zahtevo zaradi SOP blokiral. CORS omogoča strežniku API, da izrecno določi, kateri izvori smejo dostopati do njegovih virov, kar omogoča pravilno delovanje spletne aplikacije.
Kako deluje CORS: Osnove
CORS deluje prek vrste glav HTTP, ki se izmenjujejo med odjemalcem (brskalnikom) in strežnikom. Strežnik uporablja te glave, da brskalniku sporoči, ali sme dostopati do zahtevanega vira. Ključna vključena glava HTTP je Access-Control-Allow-Origin
.
Scenarij 1: Preprosta zahteva
»Preprosta zahteva« je zahteva GET, HEAD ali POST, ki izpolnjuje določena merila (npr. glava Content-Type
je ena izmed application/x-www-form-urlencoded
, multipart/form-data
ali text/plain
). V tem primeru brskalnik pošlje zahtevo neposredno strežniku, ta pa odgovori z glavo Access-Control-Allow-Origin
.
Zahteva odjemalca (z http://example.com):
GET /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
Odgovor strežnika (z http://api.example.net):
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json
{
"data": "Nekaj podatkov s strežnika"
}
V tem primeru strežnik odgovori z Access-Control-Allow-Origin: http://example.com
, kar pomeni, da so zahteve z http://example.com
dovoljene. Če se izvor v zahtevi ne ujema z vrednostjo v glavi Access-Control-Allow-Origin
(ali če glava ni prisotna), bo brskalnik blokiral odgovor in preprečil skripti na strani odjemalca dostop do podatkov.
Scenarij 2: Predpoletna zahteva (za kompleksne zahteve)
Za bolj kompleksne zahteve, kot so tiste, ki uporabljajo metode HTTP, kot so PUT, DELETE, ali tiste z glavami po meri, brskalnik izvede »predpoletno« zahtevo z metodo HTTP OPTIONS. Ta predpoletna zahteva prosi strežnik za dovoljenje, preden pošlje dejansko zahtevo. Strežnik odgovori z glavami, ki določajo, katere metode, glave in izvori so dovoljeni.
Predpoletna zahteva odjemalca (z http://example.com):
OPTIONS /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Odgovor strežnika (z http://api.example.net):
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header, Content-Type
Access-Control-Max-Age: 3600
Pojasnilo glav:
Access-Control-Allow-Origin: http://example.com
- Označuje, da so zahteve zhttp://example.com
dovoljene.Access-Control-Allow-Methods: GET, PUT, DELETE
- Določa dovoljene metode HTTP za zahteve med različnimi izvori.Access-Control-Allow-Headers: X-Custom-Header, Content-Type
- Navaja dovoljene glave po meri v dejanski zahtevi.Access-Control-Max-Age: 3600
- Določa trajanje (v sekundah), za katero lahko brskalnik predpomni odgovor predpoletne zahteve. To pomaga zmanjšati število predpoletnih zahtev.
Če odgovor predpoletne zahteve strežnika kaže, da je zahteva dovoljena, brskalnik nadaljuje z dejansko zahtevo. V nasprotnem primeru brskalnik zahtevo blokira.
Dejanska zahteva odjemalca (z http://example.com):
PUT /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
X-Custom-Header: some-value
Content-Type: application/json
{
"data": "Nekaj podatkov za posodobitev"
}
Odgovor strežnika (z http://api.example.net):
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json
{
"status": "Podatki uspešno posodobljeni"
}
Pogoste glave CORS
Tukaj je razčlenitev ključnih glav CORS, ki jih morate razumeti:
Access-Control-Allow-Origin
: Ta glava je najosnovnejša. Določa izvor(e), ki smejo dostopati do vira. Možne vrednosti vključujejo:- Določen izvor (npr.
http://example.com
). *
(zvezdica): To omogoča zahteve s katerega koli izvora. Uporabljajte previdno, saj lahko ogrozi varnost, če so vključeni občutljivi podatki. Na splošno se ji je treba izogibati v produkcijskih okoljih.
- Določen izvor (npr.
Access-Control-Allow-Methods
: Ta glava določa metode HTTP (npr. GET, POST, PUT, DELETE), ki so dovoljene za zahteve med različnimi izvori. Uporablja se v odgovoru predpoletne zahteve.Access-Control-Allow-Headers
: Ta glava navaja glave po meri, ki so dovoljene v zahtevah med različnimi izvori. Uporablja se tudi v odgovoru predpoletne zahteve.Access-Control-Allow-Credentials
: Ta glava označuje, ali strežnik dovoljuje vključitev poverilnic (npr. piškotkov, avtorizacijskih glav) v zahteve med različnimi izvori. Nastavljena mora biti natrue
, če morate pošiljati poverilnice. Na strani odjemalca morate na objektu XMLHttpRequest nastaviti tudiwithCredentials = true
.Access-Control-Expose-Headers
: Privzeto brskalniki skriptam na strani odjemalca izpostavijo le omejen nabor glav odgovora (npr.Cache-Control
,Content-Language
,Content-Type
,Expires
,Last-Modified
,Pragma
). Če želite izpostaviti druge glave, jih morate navesti v glaviAccess-Control-Expose-Headers
.Access-Control-Max-Age
: Ta glava določa največji čas (v sekundah), za katerega lahko brskalnik predpomni predpoletno zahtevo. Daljša vrednost zmanjša število predpoletnih zahtev in izboljša delovanje.
CORS v različnih strežniških jezikih
Implementacija CORS običajno vključuje konfiguracijo vaše strežniške aplikacije za pošiljanje ustreznih glav CORS. Tukaj so primeri, kako to storiti v različnih jezikih in ogrodjih:
Node.js z Expressom
Uporabite lahko paket vmesne programske opreme cors
:
const express = require('express');
const cors = require('cors');
const app = express();
// Omogoči CORS za vse izvore (UPORABLJAJTE PREVIDNO V PRODUKCIJI)
app.use(cors());
// Alternativno, konfigurirajte CORS za določene izvore
// app.use(cors({
// origin: 'http://example.com'
// }));
app.get('/data', (req, res) => {
res.json({ message: 'To je CORS-omogočeno za vse izvore!' });
});
app.listen(3000, () => {
console.log('Strežnik teče na vratih 3000');
});
Python s Flaskom
Uporabite lahko razširitev Flask-CORS
:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
# Alternativno, konfigurirajte CORS za določene izvore
# CORS(app, resources={r"/api/*": {"origins": "http://example.com"}})
@app.route("/data")
def hello():
return {"message": "To je CORS-omogočeno za vse izvore!"}
if __name__ == '__main__':
app.run(debug=True)
Java s Spring Boot
CORS lahko konfigurirate v svoji aplikaciji Spring Boot z uporabo anotacij ali konfiguracijskih razredov:
Z uporabo anotacij:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin(origins = "http://example.com") // Dovoli zahteve z http://example.com
public class DataController {
@GetMapping("/data")
public String getData() {
return "To je CORS-omogočeno za http://example.com!";
}
}
Z uporabo konfiguracije:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/data")
.allowedOrigins("http://example.com") // Dovoli zahteve z http://example.com
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*");
}
}
PHP
"To je CORS-omogočeno za http://example.com!");
echo json_encode($data);
?>
CORS in varnostni vidiki
Čeprav CORS omogoča zahteve med različnimi izvori, je ključnega pomena, da ga implementirate varno. Tukaj je nekaj pomembnih vidikov:
- Izogibajte se uporabi
*
zaAccess-Control-Allow-Origin
v produkciji: To omogoča zahteve s katerega koli izvora, kar je lahko varnostno tveganje. Namesto tega izrecno določite izvore, ki smejo dostopati do vaših virov. - Preverite glavo
Origin
na strani strežnika: Tudi če uporabljate ogrodje, ki upravlja s konfiguracijo CORS, je dobra praksa, da preverite glavoOrigin
na strani strežnika, da zagotovite, da zahteva prihaja s pričakovanega izvora. - Bodite pozorni na
Access-Control-Allow-Credentials
: Če uporabljate poverilnice (npr. piškotke, avtorizacijske glave), poskrbite, da na strani strežnika nastaviteAccess-Control-Allow-Credentials: true
in na strani odjemalcawithCredentials = true
. Vendar se zavedajte, da uporabaAccess-Control-Allow-Origin: *
ni dovoljena, ko jeAccess-Control-Allow-Credentials
nastavljen natrue
. Dovoljene izvore morate izrecno določiti. - Pravilno konfigurirajte
Access-Control-Allow-Methods
inAccess-Control-Allow-Headers
: Dovolite le tiste metode HTTP in glave, ki so nujne za pravilno delovanje vaše aplikacije. To pomaga zmanjšati površino napada. - Uporabljajte HTTPS: Vedno uporabljajte HTTPS za svoje spletne aplikacije in API-je za zaščito podatkov med prenosom.
Odpravljanje težav s CORS
Težave s CORS so lahko frustrirajoče za odpravljanje. Tukaj je nekaj pogostih težav in kako jih rešiti:
- »No 'Access-Control-Allow-Origin' header is present on the requested resource«: To je najpogostejša napaka CORS. Pomeni, da strežnik v svojem odgovoru ne pošilja glave
Access-Control-Allow-Origin
. Dvakrat preverite svojo strežniško konfiguracijo, da se prepričate, da se glava pravilno pošilja. - »Response to preflight request doesn't pass access control check: It does not have HTTP ok status«: Ta napaka kaže, da je predpoletna zahteva spodletela. To se lahko zgodi, če strežnik ni konfiguriran za obravnavo zahtev OPTIONS ali če glavi
Access-Control-Allow-Methods
aliAccess-Control-Allow-Headers
nista pravilno konfigurirani. - »The value of the 'Access-Control-Allow-Origin' header in the response is not equal to the origin in the request«: Ta napaka pomeni, da se izvor v zahtevi ne ujema z vrednostjo v glavi
Access-Control-Allow-Origin
. Prepričajte se, da strežnik v odgovoru pošilja pravilen izvor. - Predpomnjenje brskalnika: Včasih lahko brskalniki predpomnijo odgovore CORS, kar lahko povzroči nepričakovano vedenje. Poskusite počistiti predpomnilnik brskalnika ali uporabite drug brskalnik, da vidite, ali to reši težavo. Uporabite lahko tudi glavo
Access-Control-Max-Age
za nadzor, kako dolgo brskalnik predpomni odgovor predpoletne zahteve.
Orodja za odpravljanje napak:
- Razvojna orodja brskalnika: Uporabite razvojna orodja brskalnika (običajno dostopna s pritiskom na F12) za pregled omrežnih zahtev in odgovorov. Poiščite glave in sporočila o napakah, povezana s CORS.
- Spletni preverjevalniki CORS: Obstajajo spletna orodja, ki vam lahko pomagajo preizkusiti vašo konfiguracijo CORS. Ta orodja pošljejo zahtevo vašemu strežniku in analizirajo glave odgovora, da bi odkrila morebitne težave.
Napredni scenariji CORS
Čeprav so osnovni koncepti CORS razmeroma enostavni, obstaja nekaj naprednejših scenarijev, ki jih je treba upoštevati:
- CORS s poddomenami: Če morate dovoliti zahteve z več poddomen (npr.
app1.example.com
,app2.example.com
), ne morete preprosto uporabiti zvezdice, kot je*.example.com
, v glaviAccess-Control-Allow-Origin
. Namesto tega boste morali dinamično generirati glavoAccess-Control-Allow-Origin
na podlagi glaveOrigin
v zahtevi. Ne pozabite preveriti izvora glede na beli seznam dovoljenih poddomen, da preprečite varnostne ranljivosti. - CORS z več izvori: Če morate dovoliti zahteve z več določenih izvorov, ne morete določiti več izvorov v glavi
Access-Control-Allow-Origin
(npr.Access-Control-Allow-Origin: http://example.com, http://another.com
je neveljavno). Namesto tega boste morali dinamično generirati glavoAccess-Control-Allow-Origin
na podlagi glaveOrigin
v zahtevi. - CORS in CDN-ji: Pri uporabi CDN-ja za strežbo vašega API-ja morate konfigurirati CDN tako, da posreduje glavo
Origin
vašemu izvornemu strežniku in pravilno predpomni glavoAccess-Control-Allow-Origin
. Za posebna navodila se posvetujte z dokumentacijo vašega ponudnika CDN.
Najboljše prakse CORS
Za zagotovitev varne in učinkovite implementacije CORS sledite tem najboljšim praksam:
- Načelo najmanjših privilegijev: Dovolite le minimalni nabor izvorov, metod in glav, ki so nujne za pravilno delovanje vaše aplikacije.
- Redno pregledujte konfiguracijo CORS: Ko se vaša aplikacija razvija, redno pregledujte svojo konfiguracijo CORS, da zagotovite, da je še vedno ustrezna in varna.
- Uporabite ogrodje ali knjižnico: Izkoristite obstoječa ogrodja ali knjižnice, ki zagotavljajo vgrajeno podporo za CORS. To lahko poenostavi implementacijo in zmanjša tveganje za napake.
- Spremljajte kršitve CORS: Implementirajte spremljanje za odkrivanje in odzivanje na morebitne kršitve CORS.
- Ostanite na tekočem: Bodite na tekočem z najnovejšimi specifikacijami CORS in varnostnimi priporočili.
Zaključek
CORS je ključen varnostni mehanizem, ki omogoča nadzorovane zahteve med različnimi izvori v spletnih aplikacijah. Razumevanje delovanja CORS in pravilne konfiguracije je bistveno za vsakega spletnega razvijalca. Z upoštevanjem smernic in najboljših praks, opisanih v tem celovitem vodniku, lahko gradite varne in funkcionalne spletne aplikacije, ki nemoteno komunicirajo z viri iz različnih izvorov.
Ne pozabite, da vedno dajete prednost varnosti in se izogibate uporabi preveč popustljivih konfiguracij CORS. S skrbnim upoštevanjem varnostnih posledic vaših nastavitev CORS lahko zaščitite svoje aplikacije in podatke pred nepooblaščenim dostopom.
Upamo, da vam je ta vodnik pomagal razumeti CORS. Veselo kodiranje!