🌐 Was ist CORS?
📖 Definition
CORS (Cross-Origin Resource Sharing, Ressourcenfreigabe zwischen verschiedenen Ursprüngen) ist ein Sicherheitsmechanismus, der Browsern mitteilt, den Zugriff auf Ressourcen von verschiedenen Ursprüngen (origin) zu erlauben. Browser schränken Cross-Origin-Ressourcenanfragen standardmäßig aus Sicherheitsgründen ein, und CORS ist die Methode, dies sicher zu ermöglichen.
🎯 Verstehen mit Analogie
Wohnungs-Sicherheitssystem
Stellen Sie sich vor, Sie leben in Gebäude A:
- Gleicher Ursprung (Same-Origin): Anruf von A-101 an A-Büro → Frei erlaubt ✅
- Cross-Origin: Anruf von A-101 an B-Büro → Sicherheitsprüfung erforderlich 🔒
- CORS-Einstellung: Gebäude B sagt "Ich nehme auch Anrufe von Gebäude A an" → Anruf erlaubt ✅
CORS ist so, es ist die Erlaubnis, die für den Zugriff auf Ressourcen anderer Gebäude (Ursprünge) erforderlich ist!
⚙️ Funktionsweise
1. Was ist Ursprung (Origin)?
Ursprung ist die Kombination aus Protokoll, Domain und Port:
https://www.example.com:443/page
│ │ │ │ │
│ │ │ │ └─ Pfad (nicht mit Ursprung verbunden)
│ │ │ └────── Port (443 wenn weggelassen)
│ │ └────────────────── Domain
│ └────────────────────── Protokoll
└───────────────────────────── Ursprung (Origin)
2. Gleicher Ursprung vs Cross-Origin
// Aktuelle Seite: https://www.example.com
✅ Gleicher Ursprung (Same-Origin)
- https://www.example.com/page
- https://www.example.com/api/users
❌ Cross-Origin
- http://www.example.com // Anderes Protokoll
- https://api.example.com // Andere Domain
- https://www.example.com:8080 // Anderer Port
3. CORS-Anfrageprozess
Simple Request (Einfache Anfrage)
1. Browser → Server: Anfrage senden
GET https://api.example.com/data
Origin: https://www.mysite.com
2. Server → Browser: Antwort
Access-Control-Allow-Origin: https://www.mysite.com
3. Browser: Antwort prüfen
- Wenn Ursprung erlaubt → Daten liefern ✅
- Wenn nicht erlaubt → CORS-Fehler ❌
Preflight Request (Vorab-Anfrage)
1. Browser → Server: Vorab-Prüfung (OPTIONS)
OPTIONS https://api.example.com/data
Origin: https://www.mysite.com
Access-Control-Request-Method: POST
2. Server → Browser: Erlaubnis-Antwort
Access-Control-Allow-Origin: https://www.mysite.com
Access-Control-Allow-Methods: POST, GET
Access-Control-Max-Age: 3600
3. Browser → Server: Echte Anfrage (POST)
POST https://api.example.com/data
4. Server → Browser: Daten-Antwort
💡 Echte Beispiele
CORS-Fehler auftritt
// Frontend (https://www.mysite.com)
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
// ❌ Konsolenfehler
// Access to fetch at 'https://api.example.com/users' from origin
// 'https://www.mysite.com' has been blocked by CORS policy:
// No 'Access-Control-Allow-Origin' header is present on the
// requested resource.
CORS auf dem Server aktivieren
Express.js (Node.js)
const express = require('express');
const cors = require('cors');
const app = express();
// Methode 1: Alle Ursprünge erlauben (Entwicklung)
app.use(cors());
// Methode 2: Spezifischen Ursprung erlauben (Produktion empfohlen)
app.use(cors({
origin: 'https://www.mysite.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true, // Cookies einschließen
maxAge: 3600 // Preflight-Cache-Zeit (Sekunden)
}));
// Methode 3: Mehrere Ursprünge erlauben
const allowedOrigins = [
'https://www.mysite.com',
'https://admin.mysite.com'
];
app.use(cors({
origin: function(origin, callback) {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
}));
// API-Endpunkt
app.get('/api/users', (req, res) => {
res.json({ users: ['Alice', 'Bob'] });
});
app.listen(3000);
Manuelle Header-Einstellung
app.use((req, res, next) => {
// Ursprung erlauben
res.header('Access-Control-Allow-Origin', 'https://www.mysite.com');
// Methoden erlauben
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
// Header erlauben
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// Authentifizierungsinformationen erlauben
res.header('Access-Control-Allow-Credentials', 'true');
// Preflight-Anfrage behandeln
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
Python Flask
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
# Alle Ursprünge erlauben
CORS(app)
# Nur spezifischen Ursprung erlauben
CORS(app, resources={
r"/api/*": {
"origins": ["https://www.mysite.com"],
"methods": ["GET", "POST"],
"allow_headers": ["Content-Type"]
}
})
@app.route('/api/users')
def get_users():
return {'users': ['Alice', 'Bob']}
Nginx-Konfiguration
server {
listen 80;
server_name api.example.com;
location /api {
# CORS-Header hinzufügen
add_header 'Access-Control-Allow-Origin' 'https://www.mysite.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
# Preflight-Anfrage behandeln
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://backend;
}
}
🤔 Häufige Fragen
F1. Warum wird CORS benötigt?
A: Für Sicherheit. Ohne CORS:
// Bösartige Website (evil.com)
fetch('https://bank.com/api/transfer', {
method: 'POST',
credentials: 'include', // Enthält Bank-Cookies des Benutzers
body: JSON.stringify({
to: 'hacker-account',
amount: 1000000
})
});
// CORS blockiert solche Angriffe!
F2. Wie löst man CORS-Fehler?
A: Je nach Situation:
// 1. Wenn Sie den Server kontrollieren → CORS-Header hinzufügen (empfohlen)
app.use(cors({ origin: 'https://frontend.com' }));
// 2. Wenn Sie den Server nicht kontrollieren → Proxy-Server verwenden
// package.json (Create React App)
{
"proxy": "https://api.example.com"
}
// 3. Entwicklungsumgebung → Proxy-Middleware
// setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use('/api', createProxyMiddleware({
target: 'https://api.example.com',
changeOrigin: true
}));
};
// 4. Browser-Erweiterung (nur Entwicklung!)
// Verwenden Sie Erweiterungen wie "CORS Unblock"
// ⚠️ Niemals in Produktion verwenden!
F3. Wann credentials: 'include' verwenden?
A: Beim Senden von Cookies oder Authentifizierungsinformationen:
// Frontend
fetch('https://api.example.com/profile', {
credentials: 'include' // Cookies einschließen
});
// Backend - Muss Ursprung explizit angeben
app.use(cors({
origin: 'https://www.mysite.com', // Kann '*' nicht verwenden!
credentials: true
}));
// ❌ Falsches Beispiel
app.use(cors({
origin: '*', // Platzhalter
credentials: true // Kann nicht mit credentials verwendet werden!
}));
F4. Unterschied zwischen Simple Request und Preflight Request?
A: Abhängig von Bedingungen:
// ✅ Simple Request (direkte Anfrage)
// - Methode: GET, HEAD, POST
// - Header: Nur Basis-Header wie Accept, Content-Type
// - Content-Type: text/plain, multipart/form-data,
// application/x-www-form-urlencoded
fetch('https://api.example.com/data', {
method: 'GET'
});
// ⚠️ Preflight Request (Anfrage nach Preflight)
// - Methode: PUT, DELETE, PATCH
// - Benutzerdefinierte Header: Authorization, etc.
// - Content-Type: application/json
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json', // Erfordert Preflight
'Authorization': 'Bearer token' // Erfordert Preflight
},
body: JSON.stringify({ name: 'Alice' })
});
F5. Unterschied zwischen CORS und CSRF?
A: Völlig unterschiedliche Sicherheitskonzepte:
CORS (Cross-Origin Resource Sharing)
├─ Zweck: Cross-Origin-Ressourcenzugriff erlauben
├─ Betrieb: Browser blockiert/erlaubt Antworten
└─ Lösung: Erlaubnis-Header auf Server hinzufügen
CSRF (Cross-Site Request Forgery)
├─ Zweck: Gefälschte Anfragen verhindern
├─ Betrieb: Bösartige Website sendet Anfragen
└─ Lösung: CSRF-Tokens verwenden
🎓 Nächste Schritte
Nach dem Verständnis von CORS, lernen Sie:
- Was ist HTTPS? (Dokument in Vorbereitung) - Weitere wichtige Web-Sicherheit
- JWT-Token (Dokument in Vorbereitung) - API-Authentifizierungsmethode
- Was ist eine API? - API-Grundkonzepte
Debugging-Tools
// In Browser-Entwicklertools überprüfen
// Network-Tab → Anfrage auswählen → Headers-Tab
// Request Headers
Origin: https://www.mysite.com
Access-Control-Request-Method: POST
// Response Headers
Access-Control-Allow-Origin: https://www.mysite.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Max-Age: 3600
🎬 Zusammenfassung
CORS ist ein zentrales Web-Sicherheitskonzept:
- Ursprung: Kombination aus Protokoll + Domain + Port
- Same-Origin Policy: Blockiert verschiedene Ursprünge standardmäßig
- CORS: Erlaubt verschiedene Ursprünge sicher
- Preflight: Vorab-Prüfung für komplexe Anfragen
Wenn CORS-Fehler auftreten, keine Panik - lösen Sie sie sicher, indem Sie geeignete Header auf dem Server setzen! 🌐✨