Umfassende Anleitung zur Behebung des Problems, dass Cookies in Cross-Origin-Anfragen (CORS) nicht gesendet werden
Wenn Sie mit einem Szenario konfrontiert waren, in dem der Server das Cookie korrekt setzt (in der Browserantwort sichtbar), der Browser dieses Cookie jedoch bei nachfolgenden Anfragen nicht an den Server zurücksendet, ist diese Anleitung für Sie geeignet. Dieses Problem tritt fast immer auf, wenn sich das Frontend und Backend Ihres Projekts auf zwei verschiedenen Domänen oder Ports befinden — zum Beispiel Frontend auf app.example.com und API auf api.example.com.
Warum passiert das?
Moderne Browser erzwingen zwei strenge Sicherheitsrichtlinien, um CSRF-Angriffe und Session-Hijacking zu verhindern:
- CORS-Richtlinie: Standardmäßig erlaubt der Browser nicht, dass domänenübergreifende Anfragen Anmeldeinformationen (wie Cookies) enthalten, es sei denn, der Server erlaubt dies ausdrücklich.
- SameSite-Richtlinie: Ab Chrome 80 werden Cookies standardmäßig mit dem Verhalten
SameSite=Laxbehandelt, was bedeutet, dass sie nicht in domänenübergreifenden Anfragen gesendet werden, es sei denn, sie werden ausdrücklich mitSameSite=Nonedefiniert.
Der wichtige Punkt ist, dass zur Lösung dieses Problems sowohl die Client- als auch die Serverseite korrekt konfiguriert werden müssen. Nur eine Seite zu ändern, reicht nicht aus.
Schritt 1: Korrekte Serverkonfiguration
Drei goldene Regeln auf der Serverseite
Regel 1 — Anmeldeinformationen aktivieren: Der Server-Antwort-Header muss den folgenden Wert enthalten:
Access-Control-Allow-Credentials: true
Regel 2 — Kein Platzhalter: Wenn Anmeldeinformationen aktiviert sind, dürfen Sie das Platzhalterzeichen * im Access-Control-Allow-Origin-Header nicht verwenden. Sie müssen die genaue vollständige Domain-Adresse des Frontends angeben:
Access-Control-Allow-Origin: https://app.example.com
Regel 3 — Cookie-Attribute: Das Cookie muss mit zwei Attributen gesetzt werden: SameSite=None und Secure. Ohne diese beiden Attribute speichert der Browser das Cookie, sendet es jedoch niemals in domänenübergreifenden Anfragen.
Beispielcode in Node.js (Express)
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://app.example.com', // Exakte Frontend-Domain, ohne /
credentials: true
}));
app.post('/login', (req, res) => {
res.cookie('session_token', 'abc123', {
httpOnly: true, // Verhindert JavaScript-Zugriff auf das Cookie
secure: true, // Nur über HTTPS senden
sameSite: 'none', // Senden in Cross-Origin-Anfragen erlauben
maxAge: 24 * 60 * 60 * 1000
});
res.json({ message: 'Anmeldung erfolgreich' });
});
Beispielcode in PHP
<?php
// Geben Sie die exakte Frontend-Domain an, nicht *
header("Access-Control-Allow-Origin: https://app.example.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
// Auf Preflight-Anfrage antworten
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
// Das Cookie mit den erforderlichen Attributen setzen
setcookie('session_token', 'abc123', [
'expires' => time() + 86400,
'path' => '/',
'secure' => true, // Erforderlich
'httponly' => true,
'samesite' => 'None' // Erforderlich für Cross-Origin
]);
Hinweis: Wenn Sie Laravel verwenden, setzen Sie supports_credentials in der Datei config/cors.php auf true und fügen Sie die Frontend-Domain zum Array allowed_origins hinzu.
Schritt 2: Korrekte Client-Konfiguration (Frontend)
Selbst bei vollständiger Serverkonfiguration sendet der Browser immer noch keine Cookies, es sei denn, Sie erklären auf der Client-Seite ausdrücklich, dass diese Anfrage "mit Anmeldeinformationen" ist.
Verwendung der Fetch API
fetch('https://api.example.com/user/profile', {
method: 'GET',
credentials: 'include' // Diese Zeile ist der Schlüssel zur Lösung des Problems
})
.then(res => res.json())
.then(data => console.log(data));
Verwendung von Axios
// Für eine bestimmte Anfrage
axios.get('https://api.example.com/user/profile', {
withCredentials: true
});
// Oder global für das gesamte Projekt
axios.defaults.withCredentials = true;
Fehlerbehebungs-Checkliste
Wenn das Problem nach Anwendung der oben genannten Maßnahmen weiterhin besteht, überprüfen Sie diese Punkte in der angegebenen Reihenfolge:
- ✅ Sind beide Seiten auf HTTPS? Das
Secure-Attribut bedeutet, dass das Cookie nur über verschlüsselte Verbindungen funktioniert. Wenn Ihre Website auf HTTP ist, akzeptiert der Browser das Cookie nicht. (Ausnahme: Entwicklungsumgebung auflocalhost) - ✅ Ist die Origin-Adresse exakt? Die
Access-Control-Allow-Origin-Adresse muss exakt mit der URL übereinstimmen, die Sie im Browser sehen. Selbst ein Unterschied inwwwoder ein abschließender Schrägstrich/führt zu einem Fehler. - ✅ Ist die OPTIONS-Anfrage erfolgreich? Überprüfen Sie im Network-Tab der Browser-Entwicklertools die Preflight-Anfrage (mit der OPTIONS-Methode). Diese Anfrage muss mit dem Code 200 oder 204 und den korrekten CORS-Headern beantwortet werden.
- ✅ Ist das Cookie gespeichert? Gehen Sie im Browser zu DevTools ← Application ← Cookies und stellen Sie sicher, dass das Cookie mit den Attributen
SecureundSameSite=Nonegespeichert ist. - ✅ Haben Sie einen Proxy oder eine zwischengeschaltete Firewall? Manchmal überschreiben Cloudflare oder Webserver wie Nginx Header. Überprüfen Sie auch deren Konfiguration.
Zusammenfassung
Das Senden von Cookies in domänenübergreifenden Anfragen erfordert die Koordination von drei Faktoren: der Server mit Access-Control-Allow-Credentials: true und exaktem Origin, das Cookie mit den Attributen SameSite=None; Secure und der Client mit Aktivierung von credentials: 'include' oder withCredentials: true. Wenn Sie diese drei Punkte beachten, wird das Problem vollständig behoben.
Zuverlässige Infrastruktur, Seelenfrieden für Entwickler
Die korrekte Implementierung von CORS und die Cookie-Verwaltung sind nur ein Teil der Geschichte; die Infrastruktur, auf der Ihr Projekt läuft, spielt ebenfalls eine entscheidende Rolle für die Stabilität und Sicherheit des Dienstes:
Radib Hosting — Hochgeschwindigkeits-Webhosting mit vollständiger Unterstützung für kostenloses SSL und Standard-Header-Konfiguration; eine ideale Wahl für das Hosting des Frontends und Backends Ihrer Projekte.
Radib Virtual Server — Wenn Ihr Projekt vollständigen Zugriff, dedizierte Ressourcen und Freiheit bei der Webserver-Konfiguration (Nginx/Apache) erfordert, sind Radib virtuelle Server mit leistungsstarker Hardware und stabilem Netzwerk die beste Wahl für professionelle APIs.
Radib Debugging- und Sicherheitsdienste — Wenn Sie mit komplexen CORS-Fehlern, Authentifizierungsproblemen oder Sicherheitsherausforderungen zu kämpfen haben, steht das technische Team von Radib mit seiner tiefgreifenden Erfahrung in der Fehlersuche und Sicherung von Webanwendungen an Ihrer Seite, um das Problem an der Wurzel zu lösen.


