Set-Cookie
The
Set-Cookie
HTTP response header is used to send a cookie from the server to the user agent, so that 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.
Warning:
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 Response header Forbidden header name Forbidden response header nameSyntax
http
Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<number>
Set-Cookie: <cookie-name>=<cookie-value>; Partitioned
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
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
Attributes
-
Domain=<domain-value>
Optional -
Expires=<date>
Optional
Indicates the maximum lifetime of the cookie as an HTTP-date timestamp.
See
-
HttpOnly
Optional
Forbids JavaScript from accessing the cookie, for example, through the
-
Max-Age=<number>
Optional -
Partitioned
Optional ExperimentalIndicates that the cookie should be stored using partitioned storage. See Cookies Having Independent Partitioned State (CHIPS) for more details.
-
Path=<path-value>
Optional
A
<cookie-name>
can contain any US-ASCII characters except for: control characters (ASCII characters 0 up to 31 and ASCII character 127) or separator characters (space, tab and the characters:
( ) < > @ , ; : \ " / [ ] ? = { }
)
A
<cookie-value>
can optionally be wrapped in double quotes and include any US-ASCII character excluding control characters (ASCII characters 0 up to 31 and ASCII character 127),
Whitespace
, double quotes, commas, semicolons, and backslashes.
<cookie-value>
.
Note:
Some
<cookie-name>
have a specific semantic:
__Secure-
prefix
: Cookies with 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, are not sent to subdomains), and the path must be
/
.
Defines the host to which the cookie will be sent.
Only the current domain can be set as the value, or a domain of a higher order, unless it is a public suffix. Setting the domain will make the cookie available to it, as well as to all its subdomains.
If omitted, this attribute defaults to the host of the current document URL, not including subdomains.
Contrary to earlier specifications, leading dots in domain names (
.example.com
) are ignored.
Multiple host/domain values are not allowed, but if a domain is specified, then subdomains are always included.
Date
for the required formatting.
If unspecified, the cookie becomes a
session cookie
.
A session finishes when the client shuts down, after which
the session cookie is removed.
Warning: Many web browsers have a session restore feature that will save all tabs and restore them the 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.
Document.cookie
property.
Note that a cookie that has been created with
HttpOnly
will still be sent with JavaScript-initiated requests, for example, when calling
XMLHttpRequest.send()
or
fetch()
.
This mitigates attacks against cross-site scripting (
XSS
).
Indicates the number of seconds until the cookie expires. A zero or negative number will expire the cookie immediately. If both
Expires
and
Max-Age
are set,
Max-Age
has precedence.
Indicates the path that
must
exist in the requested URL for the browser to send the
Cookie
header.
The forward slash (
/
) character is interpreted as a directory separator, and subdirectories are matched as well. For example, for
Path=/docs
,
/docs
,
/docs/
,
/docs/Web/
, and
/docs/Web/HTTP
will all match.
/
,
/docsets
,
/fr/docs
will not match.
SameSite=<samesite-value>
Optional
The possible attribute values are:
Strict
SameSite=Strict
attribute are sent.
Means that the cookie is not sent on cross-site requests, such as on requests to load images or frames, but is sent when a user is navigating to the origin site from an external site (for example, when following a link).
This is the default behavior if the
SameSite
attribute is not specified.
means that the browser sends the cookie with both cross-site and same-site requests.
The
Secure
attribute must also be set when setting this value, like so
SameSite=None; Secure
. If
Secure
is missing an error will be logged:
Cookie "myCookie" rejected because it has the "SameSite=None" attribute but is missing the "secure" attribute. This Set-Cookie was blocked because it had the "SameSite=None" attribute but did not have the "Secure" attribute, which is required in order to use "SameSite=None".Note: A
Secure
cookie is only sent to the server with an encrypted request over the HTTPS protocol. Note that insecure sites (http:
) can't set cookies with theSecure
directive, and therefore can't useSameSite=None
.
Secure
OptionalIndicates that the cookie is sent to the server only when a request is made with the https:
scheme (except on localhost), and therefore, is more resistant 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 either with access to the client's hard disk or from JavaScript if the HttpOnly
cookie attribute is not set.
Insecure sites (http:
) cannot set cookies with the Secure
attribute (since Chrome 52 and Firefox 52). The https:
requirements are ignored when the Secure
attribute is set by localhost (since Chrome 89 and Firefox 75).
Examples
Session cookie
Session cookies
are removed when the client shuts down. Cookies are session cookies if they do not specify the
Expires
or
Max-Age
attribute.
http
Set-Cookie: sessionId=38afes7a8
Permanent cookie
Permanent cookies
are removed at a specific date (
Expires
) or after a specific length of time (
Max-Age
) and not when the client is closed.
http
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT
http
Set-Cookie: id=a3fWa; Max-Age=2592000
Invalid domains
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
:
http
Set-Cookie: qwerty=219ffwef9w0f; Domain=somecompany.co.uk
A cookie for a subdomain of the serving domain will be rejected.
The following cookie will be rejected if set by a server hosted on example.com
:
http
Set-Cookie: sessionId=e8bb43229de9; Domain=foo.example.com
Cookie prefixes
Cookie prefixes
Cookie 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.
Warning:
For clients that don't implement cookie prefixes, you cannot count on these additional assurances, and prefixed cookies will always be accepted.
http
// 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
Partitioned cookie
Partitioned cookie
http
Set-Cookie: __Host-example=34d8g; SameSite=None; Secure; Path=/; Partitioned;
Note: Partitioned cookies must be set with Secure
and Path=/
. In addition, it is recommended to use the __Host
prefix when setting partitioned cookies to make them bound to the hostname and not the registrable domain.
Specifications
Specifications
Specification |
---|
HTTP State Management Mechanism
# sane-set-cookie |
Browser compatibility
Browser compatibility
BCD tables only load in the browser
Compatibility notes
-
Starting with Chrome 52 and Firefox 52, insecure sites (
http:
) can't set cookies with the
Secure
attribute anymore.