Dansk

Afdæk hemmelighederne bag CORS (Cross-Origin Resource Sharing) og lær, hvordan du sikkert aktiverer anmodninger på tværs af domæner i dine webapplikationer. Denne omfattende guide dækker alt fra det grundlæggende til avancerede konfigurationer og sikrer problemfri og sikker kommunikation mellem forskellige oprindelser.

Afmystificering af CORS: En Omfattende Guide til Cross-Origin Resource Sharing

I nutidens forbundne web har applikationer ofte brug for at tilgå ressourcer fra forskellige oprindelser. Det er her, Cross-Origin Resource Sharing (CORS) kommer ind i billedet. CORS er en afgørende sikkerhedsmekanisme, der styrer, hvordan webbrowsere håndterer anmodninger fra én oprindelse (domæne, protokol og port) til en anden oprindelse. At forstå CORS er essentielt for enhver webudvikler for at bygge sikre og funktionelle webapplikationer.

Hvad er Same-Origin Policy?

Før vi dykker ned i CORS, er det vigtigt at forstå Same-Origin Policy (SOP). SOP er en fundamental sikkerhedsmekanisme implementeret i webbrowsere. Dens formål er at forhindre ondsindede scripts på ét website i at tilgå følsomme data på et andet website. En oprindelse er defineret ved kombinationen af protokollen (f.eks. HTTP eller HTTPS), domænet (f.eks. example.com) og portnummeret (f.eks. 80 eller 443). To URL'er betragtes som havende samme oprindelse, hvis de deler samme protokol, domæne og port.

Eksempel:

SOP begrænser scripts i at tilgå ressourcer fra en anden oprindelse, medmindre specifikke foranstaltninger, såsom CORS, er på plads for at tillade det.

Hvorfor er CORS nødvendigt?

Selvom Same-Origin Policy er afgørende for sikkerheden, kan den også være restriktiv. Mange moderne webapplikationer er afhængige af at hente data fra forskellige servere, såsom API'er eller content delivery networks (CDN'er). CORS giver en kontrolleret måde at lempe SOP på og tillade legitime anmodninger på tværs af oprindelser, samtidig med at sikkerheden opretholdes.

Overvej et scenarie, hvor en webapplikation hostet på http://example.com skal hente data fra en API-server hostet på http://api.example.net. Uden CORS ville browseren blokere denne anmodning på grund af SOP. CORS tillader API-serveren eksplicit at specificere, hvilke oprindelser der har tilladelse til at tilgå dens ressourcer, hvilket gør det muligt for webapplikationen at fungere korrekt.

Hvordan CORS virker: Det grundlæggende

CORS fungerer via en række HTTP-headere, der udveksles mellem klienten (browseren) og serveren. Serveren bruger disse headere til at informere browseren om, hvorvidt den må tilgå den anmodede ressource. Den centrale HTTP-header, der er involveret, er Access-Control-Allow-Origin.

Scenarie 1: Simpel anmodning

En "simpel anmodning" er en GET-, HEAD- eller POST-anmodning, der opfylder specifikke kriterier (f.eks. er Content-Type-headeren en af application/x-www-form-urlencoded, multipart/form-data eller text/plain). I dette tilfælde sender browseren anmodningen direkte til serveren, og serveren svarer med Access-Control-Allow-Origin-headeren.

Klientanmodning (fra http://example.com):

GET /data HTTP/1.1
Host: api.example.net
Origin: http://example.com

Serversvar (fra http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

{
  "data": "Noget data fra serveren"
}

I dette eksempel svarer serveren med Access-Control-Allow-Origin: http://example.com, hvilket indikerer, at anmodninger fra http://example.com er tilladt. Hvis oprindelsen i anmodningen ikke matcher værdien i Access-Control-Allow-Origin-headeren (eller hvis headeren ikke er til stede), vil browseren blokere svaret og forhindre klientsidens script i at tilgå dataene.

Scenarie 2: Preflight-anmodning (for komplekse anmodninger)

For mere komplekse anmodninger, såsom dem der bruger HTTP-metoder som PUT, DELETE, eller dem med brugerdefinerede headere, udfører browseren en "preflight"-anmodning ved hjælp af HTTP OPTIONS-metoden. Denne preflight-anmodning spørger serveren om tilladelse, før den faktiske anmodning sendes. Serveren svarer med headere, der specificerer, hvilke metoder, headere og oprindelser der er tilladt.

Klientens preflight-anmodning (fra 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

Serversvar (fra 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

Forklaring af headere:

Hvis serverens preflight-svar indikerer, at anmodningen er tilladt, fortsætter browseren med den faktiske anmodning. Ellers blokerer browseren anmodningen.

Klientens faktiske anmodning (fra 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": "Noget data der skal opdateres"
}

Serversvar (fra http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

{
  "status": "Data opdateret med succes"
}

Almindelige CORS-headere

Her er en oversigt over de vigtigste CORS-headere, du skal forstå:

CORS i forskellige server-side sprog

Implementering af CORS involverer typisk konfiguration af din server-side applikation til at sende de passende CORS-headere. Her er eksempler på, hvordan man gør dette i forskellige sprog og frameworks:

Node.js med Express

Du kan bruge cors middleware-pakken:

const express = require('express');
const cors = require('cors');

const app = express();

// Aktiver CORS for alle oprindelser (BRUG MED FORSIGTIGHED I PRODUKTION)
app.use(cors());

// Alternativt, konfigurer CORS for specifikke oprindelser
// app.use(cors({
//   origin: 'http://example.com'
// }));

app.get('/data', (req, res) => {
  res.json({ message: 'Dette er CORS-aktiveret for alle oprindelser!' });
});

app.listen(3000, () => {
  console.log('Serveren kører på port 3000');
});

Python med Flask

Du kan bruge Flask-CORS-udvidelsen:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Alternativt, konfigurer CORS for specifikke oprindelser
# CORS(app, resources={r"/api/*": {"origins": "http://example.com"}})

@app.route("/data")
def hello():
    return {"message": "Dette er CORS-aktiveret for alle oprindelser!"}

if __name__ == '__main__':
    app.run(debug=True)

Java med Spring Boot

Du kan konfigurere CORS i din Spring Boot-applikation ved hjælp af annotationer eller konfigurationsklasser:

Brug af annotationer:

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") // Tillad anmodninger fra http://example.com
public class DataController {

    @GetMapping("/data")
    public String getData() {
        return "Dette er CORS-aktiveret for http://example.com!";
    }
}

Brug af konfiguration:

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") // Tillad anmodninger fra http://example.com
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }
}

PHP

 "Dette er CORS-aktiveret for http://example.com!");
echo json_encode($data);
?>

CORS og sikkerhedsovervejelser

Selvom CORS muliggør anmodninger på tværs af oprindelser, er det afgørende at implementere det sikkert. Her er nogle vigtige overvejelser:

Fejlfinding af CORS-problemer

CORS-problemer kan være frustrerende at fejlfinde. Her er nogle almindelige problemer og hvordan man løser dem:

Fejlsøgningsværktøjer:

Avancerede CORS-scenarier

Selvom de grundlæggende CORS-koncepter er relativt ligetil, er der nogle mere avancerede scenarier at overveje:

Bedste praksis for CORS

For at sikre en sikker og effektiv CORS-implementering, følg disse bedste praksisser:

Konklusion

CORS er en kritisk sikkerhedsmekanisme, der muliggør kontrollerede anmodninger på tværs af oprindelser i webapplikationer. At forstå, hvordan CORS fungerer, og hvordan man konfigurerer det korrekt, er essentielt for enhver webudvikler. Ved at følge retningslinjerne og de bedste praksisser, der er beskrevet i denne omfattende guide, kan du bygge sikre og funktionelle webapplikationer, der problemfrit interagerer med ressourcer fra forskellige oprindelser.

Husk altid at prioritere sikkerhed og undgå at bruge alt for tilladende CORS-konfigurationer. Ved omhyggeligt at overveje sikkerhedskonsekvenserne af dine CORS-indstillinger kan du beskytte dine applikationer og data mod uautoriseret adgang.

Vi håber, at denne guide har hjulpet dig med at afmystificere CORS. God kodning!