An [HTTP](HTTP.md) cookie (web cookie, browser cookie) is a small piece of data that a server sends to a user's web browser. The browser may store the cookie and send it back to the same server with later requests. Typically, an [HTTP](HTTP.md) cookie is used to tell if two requests come from the same browser—keeping a user logged in, for example. It remembers stateful information for the stateless [HTTP](HTTP.md) protocol.
Cookies are mainly used for three purposes:
- Session management: Logins, shopping carts, game scores, or anything else the server should remember
- Personalization: User preferences, themes, and other settings
- Tracking: Recording and analyzing user behavior
Cookies were once used for general client-side storage. While this made sense when they were the only way to store data on the client, modern storage APIs are now recommended. Cookies are sent with every request, so they can worsen performance (especially for mobile data connections). Modern APIs for client storage are the Web Storage API (localStorage and sessionStorage) and IndexedDB.
## Using Cookies
After receiving an [HTTP](HTTP.md) request, a server can send one or more `Set-Cookie` headers with the response. The browser usually stores the cookie and sends it with requests made to the same server inside a `Cookie` [HTTP](HTTP.md) header. You can specify an expiration date or time period after which the cookie shouldn't be sent. You can also set additional restrictions to a specific [domain](Domain.md) and path to limit where the cookie is sent.
```
Set-Cookie: <cookie-name>=<cookie-value>
```
## Cookie lifetime
The lifetime of a cookie can be defined in two ways:
- _Session_ cookies are deleted when the current session ends. The browser defines when the "current session" ends, and some browsers use _session restoring_ when restarting. This can cause session cookies to last indefinitely.
- _Permanent_ cookies are deleted at a date specified by the `Expires` attribute, or after a period of time specified by the `Max-Age` attribute.
You can ensure that cookies are sent securely and aren't accessed by unintended parties or scripts in one of two ways: with the `Secure` attribute and the `HttpOnly` attribute.
A cookie with the `Secure` attribute is only sent to the server with an encrypted request over the HTTPS protocol. It's never sent with unsecured [HTTP](HTTP.md) (except on localhost), which means man-in-the-middle attackers can't access it easily. Insecure sites (with `http:` in the [URL](URL.md)) can't set cookies with the `Secure` attribute. However, don't assume that `Secure` prevents all access to sensitive information in cookies. For example, someone with access to the client's hard disk (or JavaScript if the `HttpOnly` attribute isn't set) can read and modify the information.
A cookie with the `HttpOnly` attribute is inaccessible to the JavaScript `Document.cookie`) API; it's only sent to the server. For example, cookies that persist in server-side sessions don't need to be available to JavaScript and should have the `HttpOnly` attribute. This precaution helps mitigate cross-site scripting (XSS) attacks.
If specified, then cookies are available on the server and its subdomains. For example, if you set `Domain=mozilla.org`, cookies are available on mozilla.org and its subdomains like `developer.mozilla.org`.
If the server does not specify a `Domain`, the cookies are available on the server _but not on its subdomains_. Therefore, specifying `Domain` is less restrictive than omitting it. However, it can be helpful when subdomains need to share information about a user.
The `Path` attribute indicates a [URL](URL.md) path that must exist in the requested [URL](URL.md) in order to send the `Cookie` header. The `%x2F` ("/") character is considered a directory separator, and subdirectories match as well.
The `SameSite` attribute lets servers specify whether/when cookies are sent with cross-site requests (where Site is defined by the registrable [domain](Domain.md) and the _scheme_: http or https). This provides some protection against cross-site request forgery attacks (CSRF). It takes three possible values: `Strict`, `Lax`, and `None`.
With `Strict`, the browser only sends the cookie with requests from the cookie's origin site. `Lax` is similar, except the browser also sends the cookie when the user _navigates_ to the cookie's origin site (even if the user is coming from a different site). For example, by following a link from an external site. `None` specifies that cookies are sent on both originating and cross-site requests, but _only in secure contexts_ (i.e., if `SameSite=None` then the `Secure` attribute must also be set). If no `SameSite` attribute is set, the cookie is treated as `Lax`.