Set-Cookie
Verwendung
Der Set-Cookie-Header weist den Client an, ein Name-Wert-Paar zusammen mit optionalen Attributen zu speichern, die Geltungsbereich, Lebensdauer und Sicherheitseigenschaften des Cookies steuern. Jeder Set-Cookie-Header setzt genau ein Cookie. Server, die mehrere Cookies senden, nehmen mehrere Set-Cookie-Header in dieselbe Antwort auf.
Die allgemeine Syntax besteht aus einem Cookie-Namen und einem Wert, getrennt durch ein Gleichheitszeichen, gefolgt von optionalen, durch Semikolons getrennten Attributen.
Set-Cookie: <name>=<value>; <attributes>
Der Cookie-Name akzeptiert US-ASCII-Zeichen mit Ausnahme von Steuerzeichen, Leerzeichen, Tabulatoren und den Trennzeichen ( ) < > @ , ; : \ ” / [ ] ? = { }. Der Cookie-Wert akzeptiert US-ASCII-Zeichen ohne Steuerzeichen, Leerraum, doppelte Anführungszeichen, Kommas, Semikolons und Backslashes. Werte können wahlweise in doppelte Anführungszeichen eingeschlossen werden.
Browser hindern Frontend-JavaScript daran, den Set-Cookie-Header über die Fetch API und XMLHttpRequest zu lesen. In der Fetch-Spezifikation ist der Header ein verbotener Antwort-Headername (forbidden response header name). Cookies in CORS-Antworten werden ignoriert, sofern die Anfrage keine Anmeldeinformationen enthält.
Cookie prefixes
Präfixe im Cookie-Namen erzwingen zusätzliche, vom Browser durchgesetzte Einschränkungen und geben damit Garantien darüber, wo und wie ein Cookie gesetzt wurde.
Das Präfix __Secure- setzt das Attribut Secure und einen HTTPS-Origin voraus. Dies verhindert, dass reine HTTP-Sites Cookies setzen, die denselben Namen wie ein sicheres Cookie tragen.
Set-Cookie: __Secure-ID=abc; Secure; Path=/
Das Präfix __Host- stellt strengere Anforderungen: das Attribut Secure, kein Domain-Attribut und Path auf / gesetzt. Dadurch wird das Cookie an den exakten Origin-Hostnamen gebunden, was Störungen durch Subdomains verhindert.
Set-Cookie: __Host-ID=abc; Secure; Path=/
Das Präfix __Http- erfordert sowohl das Attribut Secure als auch HttpOnly und lässt sich ausschließlich über den Set-Cookie-Header setzen, nicht über JavaScript.
Set-Cookie: __Http-ID=abc; Secure; HttpOnly
Das Präfix __Host-Http- kombiniert die Einschränkungen von __Host- und __Http- und stellt damit die restriktivste verfügbare Cookie-Bindung dar.
Set-Cookie: __Host-Http-ID=abc; Secure; HttpOnly; Path=/
Hinweis
Die Präfixe __Http- und __Host-Http- stammen aus einem eigenständigen Vorschlag zu Cookie-Präfixen und unterscheiden sich von den etablierten Präfixen __Secure- und __Host-, die von Browsern breit durchgesetzt werden. Die neueren Präfixe befinden sich weiterhin im Vorschlagsstadium.
SEO-Auswirkung
Googlebot sendet Cookies, wenn der Origin sie setzt, speichert sie jedoch nicht über einzelne Crawl-Sitzungen hinweg dauerhaft. Große Cookies auf Asset-Domains erhöhen die Anfragegröße während des Renderings. Eine cookiefreie Domain für statische Assets vermeidet diesen Mehraufwand. Vermeiden Sie es, Inhalte hinter cookieabhängiger Logik zu verbergen, die Crawler daran hindert, die Seite zu sehen.
Expires
Das Attribut Expires legt ein absolutes Ablaufdatum im HTTP-date-Format fest. Nach diesem Datum sendet der Client das Cookie nicht mehr. Wird es zusammen mit Max-Age weggelassen, wird das Cookie zu einem Session-Cookie, das beim Schließen des Clients entfernt wird. Browser gleichen Zeitabweichungen anhand des Date-Headers aus der Antwort aus.
Expires=Thu, 31 Dec 2026 23:59:59 GMT
Hinweis
Browser begrenzen den Expires-Wert auf 400 Tage ab dem Zeitpunkt, zu dem das Cookie gesetzt wurde. Diese Obergrenze erlaubt es Sites, die etwa einmal jährlich besucht werden, ihre Cookies zu behalten, und verhindert zugleich eine unbegrenzte Persistenz.
Max-Age
Das Attribut Max-Age legt die Lebensdauer des Cookies in Sekunden ab dem Zeitpunkt fest, zu dem der Client die Antwort empfängt. Ein Wert von null oder ein negativer Wert lässt das Cookie sofort ablaufen. Sind sowohl Expires als auch Max-Age vorhanden, hat Max-Age Vorrang.
Max-Age=2592000
Die Cookie Store API in JavaScript stellt über die Methode cookieStore.set() ebenfalls eine Option maxAge bereit, die dieses Attribut für die programmgesteuerte Cookie-Verwaltung abbildet. Die API erlaubt es nicht, expires und maxAge am selben Cookie gleichzeitig zu setzen.
Hinweis
Browser begrenzen den Max-Age-Wert auf 400 Tage (34.560.000 Sekunden), passend zur Obergrenze von Expires.
Domain
Das Attribut Domain gibt an, welche Hosts das Cookie erhalten. Ist es gesetzt, steht das Cookie der angegebenen Domain und allen ihren Subdomains zur Verfügung. Wird es weggelassen, gilt das Cookie standardmäßig nur für den exakten Ursprungshost und schließt Subdomains aus (ein reines Host-Cookie). Gültig sind ausschließlich die aktuelle Domain oder eine übergeordnete Domain des aktuellen Hosts. Führende Punkte werden ignoriert.
Domain=example.re
Path
Das Attribut Path beschränkt die Übertragung des Cookies auf Anfragen, die dem angegebenen URL-Pfadpräfix entsprechen. Der Schrägstrich / trennt die Pfadsegmente. Ein Cookie mit Path=/docs passt auf /docs, /docs/, /docs/Web/HTTP, aber nicht auf / oder /docsets.
Path=/
Hinweis
Das Attribut Path ist kein Sicherheitsmechanismus. Jedes Skript desselben Origins hat unabhängig von Pfadbeschränkungen Zugriff auf alle Cookies.
Secure
Das Attribut Secure beschränkt das Cookie auf HTTPS-Verbindungen. Der Browser sendet ein sicheres Cookie niemals über unverschlüsseltes HTTP. Unsichere Origins können keine Cookies mit diesem Attribut setzen. Localhost ist während der Entwicklung von der HTTPS-Anforderung ausgenommen.
HttpOnly
Das Attribut HttpOnly unterbindet den Zugriff von JavaScript auf das Cookie über document.cookie, die Cookie Store API und andere DOM-Schnittstellen. Bei HTTP-Anfragen, die von JavaScript über fetch() und XMLHttpRequest ausgelöst werden, wird das Cookie dennoch mitgesendet. Dieses Attribut entschärft Cross-Site-Scripting-Angriffe (XSS), die darauf abzielen, Cookie-Werte zu stehlen.
SameSite
Das Attribut SameSite steuert, ob der Browser das Cookie bei siteübergreifenden Anfragen mitsendet. Es sind drei Werte definiert.
Strict sendet das Cookie ausschließlich bei Anfragen derselben Site. Siteübergreifende Navigationen, einschließlich des Klicks auf einen Link von einer externen Site, enthalten das Cookie nicht.
Lax sendet das Cookie bei Anfragen derselben Site sowie bei siteübergreifenden Navigationen der obersten Ebene, bei denen sich die Adressleiste ändert. Subressourcen-Anfragen, fetch()-Aufrufe und iframe-Navigationen enthalten das Cookie nicht. Die meisten Browser verwenden standardmäßig Lax, wenn kein SameSite-Attribut angegeben ist.
None sendet das Cookie bei allen Anfragen, auch bei siteübergreifenden. Bei Verwendung von SameSite=None ist das Attribut Secure erforderlich. Cookies von einem abweichenden Schema (HTTP gegenüber HTTPS) gelten als siteübergreifend.
SameSite=Lax
Partitioned
Das Attribut Partitioned speichert das Cookie in einem partitionierten Speicher, dessen Schlüssel sowohl den Cookie-Origin als auch die Site der obersten Ebene umfasst. Ein partitioniertes Cookie, das von cdn.example.re gesetzt wurde, während es in shop.example.org eingebettet war, wird nur dann gesendet, wenn cdn.example.re in shop.example.org eingebettet ist, nicht jedoch bei Einbettung auf anderen Sites.
Dieses Attribut ist Teil des Vorschlags Cookies Having Independent Partitioned State (CHIPS). Es ermöglicht legitime siteübergreifende Cookie-Anwendungsfälle wie eingebettete Widgets, CDN-Load-Balancing und Headless-CMS-Anbieter, ohne eine vollständige siteübergreifende Tracking-Fähigkeit einzuräumen.
Das Attribut Secure ist erforderlich. Das Präfix __Host- wird empfohlen, um das Cookie an den exakten Origin zu binden.
Set-Cookie: __Host-sess=abc; SameSite=None; Secure; Path=/; Partitioned
Unterstützt von Chromium-basierten Browsern und Firefox. Safari partitioniert Drittanbieter-Cookies standardmäßig über einen eigenen Mechanismus und verwendet dieses Attribut nicht.
Beispiel
Ein Session-Cookie ohne Ablaufattribute. Das Cookie wird entfernt, sobald die Client-Sitzung endet.
Set-Cookie: sessionId=38afes7a8
Ein persistentes Cookie mit einer Lebensdauer von 30 Tagen. Das Attribut Max-Age legt den Ablauf relativ zur aktuellen Zeit fest.
Set-Cookie: id=a3fWa; Max-Age=2592000
Ein Cookie mit Sicherheitsattributen, die für Authentifizierungs-Token geeignet sind. Das Attribut HttpOnly unterbindet den JavaScript-Zugriff, Secure beschränkt auf HTTPS, und SameSite=Strict verhindert die siteübergreifende Übertragung.
Set-Cookie: __Host-token=eyJhbGci; Secure; HttpOnly; SameSite=Strict; Path=/
Ein partitioniertes Drittanbieter-Cookie für eine siteübergreifende Einbettung. Das Attribut Partitioned isoliert das Cookie auf die konkrete Site der obersten Ebene, auf der die Einbettung erscheint.
Set-Cookie: __Host-embed=34d8g; SameSite=None; Secure; Path=/; Partitioned
Mehrere Cookies, die in einer einzigen Antwort gesetzt werden. Jedes Cookie benötigt einen eigenen Set-Cookie-Header.
Set-Cookie: theme=dark; Path=/; Max-Age=31536000
Set-Cookie: __Host-sid=x8Kp2; Secure; HttpOnly; SameSite=Lax; Path=/
Fehlersuche
Cookies, die nicht dauerhaft gespeichert werden oder bei den falschen Anfragen ankommen, lassen sich häufig auf nicht zusammenpassende Attribute oder auf Durchsetzungsrichtlinien des Browsers zurückführen.
Cookie wird wegen des Secure-Flags über HTTP nicht gespeichert. Das Attribut Secure setzt eine HTTPS-Verbindung voraus. Ein mit Secure über einfaches HTTP gesetztes Cookie wird stillschweigend verworfen. Prüfen Sie das Protokoll in der Adressleiste des Browsers und untersuchen Sie die Set-Cookie-Header im Network-Tab der DevTools. Localhost ist während der Entwicklung von dieser Einschränkung ausgenommen.
Cookie wird bei siteübergreifenden Anfragen nicht gesendet (SameSite-Standardwert). Moderne Browser verwenden standardmäßig SameSite=Lax, wenn kein SameSite-Attribut vorhanden ist. Siteübergreifende Unteranfragen wie fetch()-Aufrufe, iframes und Bildabrufe enthalten das Cookie nicht. Ergänzen Sie SameSite=None; Secure, wenn das Cookie siteübergreifend übertragen werden muss, oder strukturieren Sie den Ablauf so um, dass die siteübergreifende Abhängigkeit entfällt.
Nicht übereinstimmender Cookie-Pfad. Ein mit Path=/app gesetztes Cookie wird nicht an Anfragen auf /api oder / gesendet. Stellen Sie sicher, dass der Path-Wert zu den Anfragepfaden passt, die das Cookie benötigen. Mit Path=/ steht das Cookie site-weit zur Verfügung.
Probleme mit dem Geltungsbereich des Domain-Attributs. Ein mit Domain=sub.example.re gesetztes Cookie wird nicht an example.re gesendet. Das Weglassen des Domain-Attributs erzeugt ein reines Host-Cookie, das auf den exakten Hostnamen beschränkt ist. Führende Punkte im Wert werden von Browsern ignoriert. Verwenden Sie in den DevTools das Panel Application > Cookies, um die effektive Domain jedes gespeicherten Cookies zu prüfen.
Drittanbieter-Cookie durch Datenschutzfunktionen des Browsers blockiert. Safari blockiert Drittanbieter-Cookies standardmäßig über Intelligent Tracking Prevention. Die Enhanced Tracking Protection von Firefox und die Privacy Sandbox von Chrome setzen vergleichbare Einschränkungen durch. Das Attribut Partitioned (CHIPS) bietet einen standardbasierten Weg für legitime siteübergreifende Cookie-Anwendungsfälle. Testen Sie in mehreren Browsern, um das Verhalten zu bestätigen.
Cookie überschreitet die maximale Größe. Browser erzwingen eine Grenze von etwa 4096 Byte pro Cookie (Name, Wert und Attribute zusammengenommen). Übergroße Cookies werden stillschweigend verworfen. Verlagern Sie große Nutzlasten in serverseitige Sitzungen und speichern Sie im Cookie nur eine Sitzungskennung.
Gespeicherte Cookies debuggen. Öffnen Sie DevTools > Application > Cookies, um alle Cookies der aktuellen Site einschließlich Attributen, Ablauf und Größe zu prüfen. Die API document.cookie legt HttpOnly-Cookies nicht offen. Verwenden Sie curl -v, um die rohen Set-Cookie-Header der Serverantwort zu sehen.