--- 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 ---
The Set-Cookie
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 Set-Cookie
headers should be sent in the same response.
Browsers block frontend JavaScript code from accessing the Set Cookie
header, as required by the Fetch spec, which defines Set-Cookie
as a forbidden response-header name that must be filtered out from any response exposed to frontend code.
For more information, see the guide on Using HTTP cookies.
Header type | {{Glossary("Response header")}} |
---|---|
{{Glossary("Forbidden header name")}} | no |
Forbidden response-header name | yes |
Set-Cookie: <cookie-name>=<cookie-value> Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date> Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit> Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value> Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value> Set-Cookie: <cookie-name>=<cookie-value>; Secure Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax Set-Cookie: <cookie-name>=<cookie-value>; SameSite=None; Secure // Multiple attributes are also possible, for example: Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
<cookie-name>=<cookie-value>
<cookie-name>
can be any US-ASCII characters, except control characters, spaces, or tabs. It also must not contain a separator character like the following: ( ) < > @ , ; : \ " / [ ] ? = { }
.<cookie-value>
can optionally be wrapped in double quotes and include any US-ASCII characters excluding control characters, {{glossary("Whitespace")}}, double quotes, comma, semicolon, and backslash. Encoding: 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 <cookie-value> though.__Secure-
prefix: Cookies names starting with __Secure-
(dash is part of the prefix) must be set with the secure
flag from a secure page (HTTPS).__Host-
prefix: Cookies with names starting with __Host-
must be set with the secure
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 /
.Expires=<date>
{{optional_inline}}The maximum lifetime of the cookie as an HTTP-date timestamp. See {{HTTPHeader("Date")}} for the required formatting.
If unspecified, the cookie becomes a session cookie. A session finishes when the client shuts down, and session cookies will be removed.
Warning: Many web browsers have a session restore 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.
When an Expires date is set, the deadline is relative to the client the cookie is being set on, not the server.
Max-Age=<number>
{{optional_inline}}Expires
and Max-Age
are set, Max-Age
has precedence.Domain=<domain-value>
{{optional_inline}}.example.com
) are ignored.Path=<path-value>
{{optional_inline}}Cookie
header./
) character is interpreted as a directory separator, and subdirectories will be matched as well: for Path=/docs
, /docs
, /docs/Web/
, and /docs/Web/HTTP
will all match.Secure
{{optional_inline}}https:
scheme (except on localhost), and therefore is more resistent to man-in-the-middle attacks.
Note: Do not assume that Secure
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 HttpOnly
cookie attribute is not set.
Note: Insecure sites (http:
) can't set cookies with the Secure
attribute (since Chrome 52 and Firefox 52). For Firefox, the https:
requirements are ignored when the Secure
attribute is set by localhost (since Firefox 75).
HttpOnly
{{optional_inline}}SameSite=<samesite-value>
{{optional_inline}}Standards related to the SameSite Cookies recently changed such that:
SameSite
is not specified is SameSite=Lax
. Previously the default was that cookies were sent for all requests.SameSite=None
must nowSecure
attribute (i.e. they require a secure context).The options below covers the new behaviour. See the Browser compatibility table for information about specific browser implementation (rows: "SameSite
: Defaults to Lax
" and "SameSite
: Secure context required").
Strict
: 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 SameSite=Strict
attribute are sent.Lax
: 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).SameSite
attribute is not specified.None
: The browser sends the cookie with both cross-site and same-site requests. The Secure
attribute must also be set when SameSite=None
!Session cookies are removed when the client shuts down. Cookies are session cookies if they don't specify the Expires
or Max-Age
attributes.
Set-Cookie: sessionId=38afes7a8
Instead of expiring when the client is closed, permanent cookies expire at a specific date (Expires
) or after a specific length of time (Max-Age
).
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT
Set-Cookie: id=a3fWa; Max-Age=2592000
A cookie for a domain that does not include the server that set it should be rejected by the user agent.
The following cookie will be rejected if set by a server hosted on originalcompany.com
:
Set-Cookie: qwerty=219ffwef9w0f; Domain=somecompany.co.uk
A cookie for a sub domain of the serving domain will be rejected.
The following cookie will be rejected if set by a server hosted on example.com
:
Set-Cookie: sessionId=e8bb43229de9; Domain=foo.example.com
Cookies names prefixed with __Secure-
or __Host-
can be used only if they are set with the secure
attribute from a secure (HTTPS) origin.
In addition, cookies with the __Host-
prefix must have a path of /
(meaning any path at the host) and must not have a Domain
attribute.
For clients that don't implement cookie prefixes, you cannot count on these additional assurances, and prefixed cookies will always be accepted.
// 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
Specification | Title |
---|---|
{{RFC("6265", "Set-Cookie", "4.1")}} | HTTP State Management Mechanism |
draft-ietf-httpbis-rfc6265bis-05 | Cookie Prefixes, Same-Site Cookies, and Strict Secure Cookies |
{{Compat("http.headers.Set-Cookie", 5)}}
http:
) can't set cookies with the Secure
attribute anymore.