HTTP is a stateless protocol. It means that each request-response pair is unrelated to the previous request-response.
In real life, this often turns out to be inconvenient, since sometimes we need to remember the user's authentication details or the user's shopping cart in an online store.
Here the following problem arises: how do you get the system to remember that this is a user we've only just worked with? The solution to this problem was found more than ten years ago when cookies were invented.
Let's make a request to the Hexlet website and see how this mechanism works. We'll use curl. It allows you to make HTTP requests and manage their parameters using flags. Unlike the case with telnet, we don't need to establish a connection in advance and then type a raw request.
Working with curl, you can immediately define the parameters, and it'll send all the necessary request headers, including HTTPS.
Let's execute a request to get only headers. To do so, add the --head
flag when running curl:
curl --head https://hexlet.io
HTTP/2 200
server: nginx/1.19.1
date: Thu, 16 Jul 2020 03:38:11 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-download-options: noopen
x-permitted-cross-domain-policies: none
referrer-policy: strict-origin-when-cross-origin
strict-transport-security: max-age=0
x-frame-options: ALLOW-FROM http://webvisor.com
etag: W/"eb99fa0d6ee702b85ba2a5e9b0425aea"
cache-control: max-age=0, private, must-revalidate
content-security-policy:
set-cookie: _hexlet_session2=AiUPd6RFbcrnoGnZSLAYSBzdJqxsQ4sTc%2BW0xXuOKzlenyv5GwkkbpdkD6IVDybDlD8vQcOcgGax98%2FmzIBJrz9f%2BDIJxWRpknZsRSfBXuC9yRfndovBUG6w4fTql4qp7zPozd2veFDLOU4koPVYiUQxgBLM6NkyYg%2Bhs%2BQe%2FSZezleVgMBVD%2FFC070DjV7t2eN01o26kcbd0pQsf9k1LE4JN0aDzSxu8elxLyAWkIJ5l3m%2BcI%2BpgOxk87Uwh9WdTHVuDaraiRaVJz1aZq5hr%2FgzaZiK%2Bgi6ChX60nhha1an610b1v3EE7xgkEM332uFPU0w675fHEr4APTdPDVtJRa3--qQi0cqcljC8i4klD--fXTErw9bhX7%2Fd1xfPE4Gww%3D%3D; domain=.hexlet.io; path=/; expires=Sun, 16 Aug 2020 03:38:11 GMT; secure; HttpOnly; SameSite=Lax
set-cookie: GCLB=CLTE8bzdlaS6Zg; path=/; HttpOnly; expires=Thu, 16-Jul-2020 03:39:50 GMT
x-request-id: 2f554de2-a21d-4e7d-964e-085914ac3f77
x-runtime: 0.056974
access-control-allow-origin: *
via: 1.1 google
alt-svc: clear
We can see two headers that deal with setting cookies — set-cookie. Note that each cookie is sent in a separate header.
As such, there may be a lot of headers. Inside the cookie is a key=value pair, separated from the additional parameters by a semicolon. Cookies are stored client-side in the browser and are sent back to the server the next time a request is made. They're not used directly in the browser in any way.
A good analogy is to imagine that you were given a tag after handing your jacket in at a cloakroom and then using it to find out which jacket is yours. Additionally, the number is of no value and cannot be used independently.
Cookies are divided into at least two types:
- Session
- Permanent
Session cookies are not set in our request, as we can see additional parameters in the set cookie header. If they didn't exist, then cookies would be called sessions.
The main difference between session and permanent cookies is that as soon as the browser closes, the cookie is deleted. Imagine a site where you haven't checked the "Remember me" box and closed the browser. The next time you go to the site to log in, you'll have to go through the process again. It happens because a session cookie is used.
Cookie lifetime
In this case, permanent cookies are set. They're stored on the hard disk, and their storage location may vary depending on the browser. Such cookies differ from session cookies because you can control their lifetime using the expires parameter:
expires=Thu, 16-Jul-2020 03:39:50 GMT;
The expires parameter specifies the date the cookie should be deleted, after which it won't be sent to the server.
It's worth mentioning that there's another parameter for the same purpose — MAX-AGE. Its value indicates the number of seconds after which the cookie will be deleted:
MAX-AGE=2592000;
Since some browsers don't support MAX-AGE
, some frameworks often set both parameters, so browsers ignore the one they don't need. A set-cookie header containing two parameters, MAX-AGE
and expires
, is considered valid. The standard also says that cookie names are not case-sensitive.
Domain and path parameters
The domain and path parameters set the cookie scope — the URLs to which the cookie can be sent. If they're not set, the cookie will be forwarded by default to the server only for the current path and domain.
In our example, the site's root is specified in the path:
domain=.hexlet.io; path=/;
It is a nuance in the code above. If we set domain=.hexlet.io
with a dot before the domain name, the cookie will work for all of the site's pages and also for all subdomains. If we don't set the domain parameter at all, then the cookie won't work for the subdomains, although its value will be hexlet.io
by default.
The uniqueness of cookies is determined by three parameters:
- Key (cookie name)
- Domain
- Path
It means that if a cookie needs to be set again, for example, to change its lifetime, then these parameters must match in set-cookie when the next request is made. If at least one of them is different, a new cookie will be set.
Deleting cookies
There is no header for deleting cookies. To delete it, you need to set MAX-AGE
to zero or a negative number. Also, you can set expires
in the past, then the cookie will be deleted immediately.
HttpOnly cookie
In our example, you may have noticed the additional parameter HttpOnly.
We pass HttpOnly cookies with AJAX requests, but they cannot be retrieved via JavaScript on the website page. It is an additional layer of security against XSS attacks.
Sending to the server
After we refresh the page in the browser, the next header is sent:
cookie: GCLB=CLiC7uWajOOrzAE; _hexlet_session2=gu3n8MCidqZ28VfjpzJuF74d4ohla6uYq9Q%2B2XBcalsa3VUCzURBWTXvscuzSI%2BF3lnHAN%2FUt6IJnXgkH%2B6jDKgyStVb8W%2BLHwIbypoxajN3fB5ksFT3Qu28RvDQpL6hBmqq7V2eFdfLMGtkmtcpfAUYNGffwaBAlQyQKnvhkCpEf5IIWkwWfe9Nt8dG3lIueeir9fGxZP7Fpcw9IP9HfgSansgXugtFI1rw06UhgrrK%2BEnaf4EmIgVdH6KYpDBKXpUUXz8vFRvkOMX5j%2BZNMTu%2BKDBzmGlFjcm1mCZl4ozZWDCocFO4CTW7z9LmzKYbcEGkUEhRbOu%2BTvLgVo80LilK--x3y6jxx%2FjYcLp5tr--9nrQ0XmAhtGAuIFvMYvWig%3D%3D
All cookies are sent with one header in the format key=value; key=value
without additional parameters.
Recommended materials
Are there any more questions? Ask them in the Discussion section.
The Hexlet support team or other students will answer you.
For full access to the course you need a professional subscription.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.