aboutsummaryrefslogtreecommitdiff
path: root/files/de/web/http/headers/set-cookie/index.html
blob: d82bd2a8160f413be3b0daf476f1584714e3c11b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
---
title: Set-Cookie
slug: Web/HTTP/Headers/Set-Cookie
tags:
  - Cookies
  - HTTP
  - NeedsTranslation
  - Reference
  - Response
  - TopicStub
  - header
  - samesite
translation_of: Web/HTTP/Headers/Set-Cookie
---
<div>{{HTTPSidebar}}</div>

<p><span class="seoSummary">The <strong><code>Set-Cookie</code></strong> HTTP response header is used to send a cookie from the server to the user agent, so the user agent can send it back to the server later. To send multiple cookies, multiple <strong><code>Set-Cookie</code></strong></span> headers should be sent in the same response.</p>

<div class="blockIndicator warning">
<p>Browsers block frontend JavaScript code from accessing the <code>Set Cookie</code> header, as required by the Fetch spec, which defines <code>Set-Cookie</code> as a <a href="https://fetch.spec.whatwg.org/#forbidden-response-header-name">forbidden response-header name</a> that <a href="https://fetch.spec.whatwg.org/#ref-for-forbidden-response-header-name%E2%91%A0">must be filtered out</a> from any response exposed to frontend code.</p>
</div>

<p>For more information, see the guide on <a href="/en-US/docs/Web/HTTP/Cookies">Using HTTP cookies</a>.</p>

<table class="properties">
 <tbody>
  <tr>
   <th scope="row">Header type</th>
   <td>{{Glossary("Response header")}}</td>
  </tr>
  <tr>
   <th scope="row">{{Glossary("Forbidden header name")}}</th>
   <td>no</td>
  </tr>
  <tr>
   <th scope="row"><a href="https://fetch.spec.whatwg.org/#forbidden-response-header-name">Forbidden response-header name</a></th>
   <td>yes</td>
  </tr>
 </tbody>
</table>

<h2 id="Syntax">Syntax</h2>

<pre class="syntaxbox notranslate">Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Expires=&lt;date&gt;
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Max-Age=&lt;non-zero-digit&gt;
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Domain=&lt;domain-value&gt;
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Path=&lt;path-value&gt;
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Secure
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; HttpOnly

Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; SameSite=Strict
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; SameSite=Lax
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; SameSite=None; Secure

// Multiple attributes are also possible, for example:
Set-Cookie: &lt;cookie-name&gt;=&lt;cookie-value&gt;; Domain=&lt;domain-value&gt;; Secure; HttpOnly
</pre>

<h2 id="Attributes">Attributes</h2>

<dl>
 <dt><code>&lt;cookie-name&gt;=&lt;cookie-value&gt;</code></dt>
 <dd>A cookie begins with a name-value pair:
 <ul>
  <li>A <code>&lt;cookie-name&gt;</code> can be any US-ASCII characters, except control characters, spaces, or tabs. It also must not contain a separator character like the following: <code>( ) &lt; &gt; @ , ; : \ " / [ ] ? = { }</code>.</li>
  <li>A <code>&lt;cookie-value&gt;</code> can optionally be wrapped in double quotes and include any US-ASCII characters excluding control characters, {{glossary("Whitespace")}}, double quotes, comma, semicolon, and backslash. <strong>Encoding</strong>: Many implementations perform URL encoding on cookie values, however it is not required per the RFC specification. It does help satisfying the requirements about which characters are allowed for &lt;cookie-value&gt; though.</li>
  <li><strong><code>__Secure-</code> prefix</strong>: Cookies names starting with<code> __Secure-</code> (dash is part of the prefix) must be set with the <code>secure</code> flag from a secure page (HTTPS).</li>
  <li><strong><code>__Host-</code> prefix</strong>: Cookies with names starting with <code>__Host-</code> must be set with the <code>secure</code> flag, must be from a secure page (HTTPS), must not have a domain specified (and therefore aren't sent to subdomains) and the path must be <code>/</code>.</li>
 </ul>
 </dd>
 <dt><code>Expires=&lt;date&gt;</code> {{optional_inline}}</dt>
 <dd>
 <p>The maximum lifetime of the cookie as an HTTP-date timestamp. See {{HTTPHeader("Date")}} for the required formatting.</p>

 <p>If unspecified, the cookie becomes a <strong>session cookie</strong>. A session finishes when the client shuts down, and session cookies will be removed.</p>

 <div class="blockIndicator warning">
 <p><strong>Warning:</strong> Many web browsers have a <em>session restore</em> feature that will save all tabs and restore them next time the browser is used. Session cookies will also be restored, as if the browser was never closed.</p>
 </div>

 <p>When an Expires date is set, the deadline is relative to the <em>client</em> the cookie is being set on, not the server.</p>
 </dd>
 <dt><code>Max-Age=&lt;number&gt; </code>{{optional_inline}}</dt>
 <dd>Number of seconds until the cookie expires. A zero or negative number will expire the cookie immediately. If both <code>Expires</code> and <code>Max-Age</code> are set, <code>Max-Age</code> has precedence.</dd>
 <dt><code>Domain=&lt;domain-value&gt;</code> {{optional_inline}}</dt>
 <dd>Host to which the cookie will be sent.
 <ul>
  <li>If omitted, defaults to the host of the current document URL, not including subdomains.</li>
  <li>Contrary to earlier specifications, leading dots in domain names (<code>.example.com</code>) are ignored.</li>
  <li>Multiple host/domain values are <em>not</em> allowed, but if a domain <em>is</em> specified, then subdomains are always included.</li>
 </ul>
 </dd>
 <dt><code>Path=&lt;path-value&gt;</code> {{optional_inline}}</dt>
 <dd>A path that must exist in the requested URL, or the browser won't send the <code>Cookie</code> header.</dd>
 <dd>The forward slash (<code>/</code>) character is interpreted as a directory separator, and subdirectories will be matched as well: for <code>Path=/docs</code>, <code>/docs</code>, <code>/docs/Web/</code>, and <code>/docs/Web/HTTP</code> will all match.</dd>
 <dt id="Secure"><code>Secure</code> {{optional_inline}}</dt>
 <dd>Cookie is only sent to the server when a request is made with the <code>https:</code> scheme (except on localhost), and therefore is more resistent to <a href="/en-US/docs/Glossary/MitM">man-in-the-middle</a> attacks.
 <p class="note"><strong>Note:</strong> Do not assume that <code>Secure</code> prevents all access to sensitive information in cookies (session keys, login details, etc.). Cookies with this attribute can still be read/modified with access to the client's hard disk, or from JavaScript if the <code>HttpOnly</code> cookie attribute is not set.</p>

 <p class="note"><strong>Note:</strong> Insecure sites (<code>http:</code>) can't set cookies with the <code>Secure</code> attribute (since Chrome 52 and Firefox 52). For Firefox, the <code>https:</code> requirements are ignored when the <code>Secure</code> attribute is set by localhost (since Firefox 75).</p>
 </dd>
 <dt id="HttpOnly"><code>HttpOnly</code> {{optional_inline}}</dt>
 <dd>Forbids JavaScript from accessing the cookie, for example, through the {{domxref("Document.cookie")}} property. Note that a cookie that has been created with HttpOnly will still be sent with JavaScript-initiated requests, e.g. when calling {{domxref("XMLHttpRequest.send()")}} or {{domxref("fetch()")}}. This mitigates attacks against cross-site scripting ({{Glossary("XSS")}}).</dd>
 <dt id="SameSite"><code>SameSite=&lt;samesite-value&gt;</code> {{optional_inline}}</dt>
 <dd>Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks ({{Glossary("CSRF")}}).</dd>
 <dd>
 <div class="note">
 <p>Standards related to the <a href="/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite">SameSite Cookies</a> recently changed such that:</p>

 <ol>
  <li>The cookie-sending behaviour if <code>SameSite</code> is not specified is <code>SameSite=Lax</code>. Previously the default was that cookies were sent for all requests.</li>
  <li>Cookies with <code>SameSite=None</code> must now<br>
   also specify the <code>Secure</code> attribute (i.e. they require a secure context).</li>
 </ol>

 <p>The options below covers the new behaviour. See the <a href="/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#Browser_compatibility">Browser compatibility</a> table for information about specific browser implementation (rows: "<code>SameSite</code>: Defaults to <code>Lax</code>" and "<code>SameSite</code>: Secure context required").</p>
 </div>
 Inline options are:

 <ul>
  <li><code>Strict</code>: The browser sends the cookie only for same-site requests (that is, requests originating from the same site that set the cookie). If the request originated from a different URL than the current one, no cookies with the <code>SameSite=Strict</code> attribute are sent.</li>
  <li><code>Lax</code>: The cookie is not sent on cross-site requests, such as calls to load images or frames, but is sent when a user is navigating to the origin site from an external site (e.g. if following a link).<br>
   This is the default behaviour if the <code>SameSite</code> attribute is not specified.</li>
  <li><code>None</code>: The browser sends the cookie with both cross-site and same-site requests. The <code>Secure</code> attribute must also be set when <code>SameSite=None</code>!</li>
 </ul>
 </dd>
</dl>

<h2 id="Examples">Examples</h2>

<h3 id="Session_cookie">Session cookie</h3>

<p><strong>Session cookies</strong> are removed when the client shuts down. Cookies are session cookies if they don't specify the <code>Expires</code> or <code>Max-Age</code> attributes.</p>

<pre class="notranslate">Set-Cookie: sessionId=38afes7a8</pre>

<h3 id="Permanent_cookie">Permanent cookie</h3>

<p>Instead of expiring when the client is closed, <strong>permanent cookies</strong> expire at a specific date (<code>Expires</code>) or after a specific length of time (<code>Max-Age</code>).</p>

<pre class="notranslate">Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT
</pre>

<pre class="notranslate">Set-Cookie: id=a3fWa; Max-Age=2592000</pre>

<h3 id="Invalid_domains">Invalid domains</h3>

<p>A cookie for a domain that does not include the server that set it <a href="https://tools.ietf.org/html/rfc6265#section-4.1.2.3">should be rejected by the user agent</a>.</p>

<p>The following cookie will be rejected if set by a server hosted on <code>originalcompany.com</code>:</p>

<pre class="notranslate">Set-Cookie: qwerty=219ffwef9w0f; Domain=somecompany.co.uk</pre>

<p>A cookie for a sub domain of the serving domain will be rejected.</p>

<p>The following cookie will be rejected if set by a server hosted on <code>example.com</code>:</p>

<pre class="notranslate">Set-Cookie: sessionId=e8bb43229de9; Domain=foo.example.com</pre>

<h3 id="Cookie_prefixes">Cookie prefixes</h3>

<p>Cookies names prefixed with <code>__Secure-</code> or <code>__Host-</code> can be used only if they are set with the <code>secure</code> attribute from a secure (HTTPS) origin.</p>

<p>In addition, cookies with the <code>__Host-</code> prefix must have a path of <code>/</code> (meaning any path at the host) and must not have a <code>Domain</code> attribute.</p>

<div class="blockIndicator warning">
<p>For clients that don't implement cookie prefixes, you cannot count on these additional assurances, and prefixed cookies will always be accepted.</p>
</div>

<pre class="notranslate">// Both accepted when from a secure origin (HTTPS)
Set-Cookie: __Secure-ID=123; Secure; Domain=example.com
Set-Cookie: __Host-ID=123; Secure; Path=/

// Rejected due to missing Secure attribute
Set-Cookie: __Secure-id=1

// Rejected due to the missing Path=/ attribute
Set-Cookie: __Host-id=1; Secure

// Rejected due to setting a Domain
Set-Cookie: __Host-id=1; Secure; Path=/; Domain=example.com
</pre>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Title</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{RFC("6265", "Set-Cookie", "4.1")}}</td>
   <td>HTTP State Management Mechanism</td>
  </tr>
  <tr>
   <td><a href="https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-05">draft-ietf-httpbis-rfc6265bis-05</a></td>
   <td>Cookie Prefixes, Same-Site Cookies, and Strict Secure Cookies</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>

<p>{{Compat("http.headers.Set-Cookie", 5)}}</p>

<h2 id="Compatibility_notes">Compatibility notes</h2>

<ul>
 <li>Starting with Chrome 52 and Firefox 52, insecure sites (<code>http:</code>) can't set cookies with the <code>Secure</code> attribute anymore.</li>
</ul>

<h2 id="See_also">See also</h2>

<ul>
 <li><a href="/en-US/docs/Web/HTTP/Cookies">HTTP cookies</a></li>
 <li>{{HTTPHeader("Cookie")}}</li>
 <li>{{domxref("Document.cookie")}}</li>
 <li><a href="/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite">SameSite cookies</a></li>
</ul>