Cookies
Cookies and Statelessness
HTTP is a stateless protocol, which means that it doesn't inherently maintain any memory of previous interactions between the client (browser) and the server. Each request made by the client is treated as an independent transaction, unrelated to any previous requests.
This statelessness poses a challenge when web applications require maintaining user-specific information or session data across multiple requests. For example, consider a scenario where a user logs into a website and expects to stay authenticated as they navigate through different pages. Without any means of maintaining state, the server would have no way of recognizing the user's authentication status on subsequent requests.
Cookies play a crucial role in addressing the stateless problem by providing a mechanism for maintaining stateful interactions. When a server sets a cookie in the browser, it effectively stores a piece of information on the user's device. This information is then sent back to the server with subsequent requests, allowing the server to identify and recognize the user, retrieve session data, and maintain personalized experiences.
By utilizing cookies, web developers can overcome the stateless nature of the HTTP protocol and enable stateful interactions between the client and the server. Cookies serve as a means of preserving user-specific information, session management, and personalized experiences within the otherwise stateless web environment.
Adding Cookies to a Node/Express Application
Adding cookie support to a Node.js/Express application involves installing the necessary middleware and configuring it within your application.
First install the cookie-parser package:
Import the modules in your application entry file:
Add the middleware to the application with:
This middleware parses the cookies sent by the client and attaches them to the req.cookies
object in subsequent middleware and route handlers.
You can now access and manipulate cookies in your routes and middleware using the req.cookies
object.
For example, to set a cookie, you can use the res.cookie()
method:
To read a cookie, you can access it through the req.cookies
object:
To clear a cookie, you can use the res.clearCookie()
method:
Exploring the Sample Application
To see cookies in action we will take a break from the films application under development and have a look at cookies in isolation. Clone this repo into a new project.
In the example we will use cookies to store a user's favourite colour and count how many times they have visited a page.
Ensure once cloned you run:
... and launch the application with:
Notice the entry file src/app.ts
has the required set up for cookie.parser
outlined above.
Viewing Cookies in the Browser
Using the Chrome Developer Console, you can inspect and manage cookies, view their values, edit or delete specific cookies, and observe how they change as you interact with the website or web application. This can be helpful for debugging, troubleshooting, or understanding the behavior of cookies in your web development projects.
Right-click anywhere on the page and select "Inspect" or press Ctrl+Shift+I
(or Cmd+Option+I
on macOS) to open the Chrome Developer Console. Alternatively, you can also access the Developer Console by going to the Chrome menu (three dots at the top-right corner) > More Tools > Developer Tools.
Reading and Writing Cookie Values
Reviewing the application there are GET
and POST
calls to a controller methods of faveColourController
and faveColourPostController
respectively.
The faveColourController
method called with a GET
call appears as follows:
This controller retrieves the user's favorite colour from a cookie (or uses a default value), increments a visit count stored in another cookie, sets the updated visit count cookie in the response, determines the colour code based on the favorite colour, and renders the "favecolour" view with the relevant data.
- It takes two parameters:
req
(representing the request object) andres
(representing the response object). - It initializes the
myFaveColour
variable with a default value of "red". - It checks if the cookie named "cookieFaveColour" exists in the request's cookies. If it does, the value of
myFaveColour
is updated with the value of the cookie. - It initializes the
visitCount
variable with a default value of 1. - It checks if the cookie named "visitCount" exists in the request's cookies. If it does, the value of
visitCount
is updated by parsing the cookie's value as an integer and incrementing it by 1. - It sets a new cookie named "visitCount" in the response with the updated value of
visitCount
. The cookie is set to expire in 900000 milliseconds (15 minutes) and is marked ashttpOnly
, meaning it cannot be accessed or modified by client-side JavaScript. - It calls the
sortColour
function to determine thecolourCode
based on themyFaveColour
. - It renders the "favecolour" view using
res.render()
, passing an object with data to be rendered in the view. The object contains properties such as the title,faveColour
,colourCode
, andvisitCount
.
This controller handles the logic for the POST request. The controller handles the submission of a form with the user's favorite colour selection. It retrieves the selected colour, determines the colour code, sets a cookie to store the selected colour, retrieves the visit count from a cookie, and renders the "favecolour" view with the updated data.
- It takes two parameters:
req
(representing the request object) andres
(representing the response object). - It retrieves the value of the
faveColour
field from the request's body usingreq.body.faveColour
and assigns it to themyFaveColour
variable. - It calls the
sortColour
function to determine thecolourCode
based on themyFaveColour
. - It sets a new cookie named "cookieFaveColour" in the response with the value of
myFaveColour
. This cookie will store the user's selected favorite colour. - It retrieves the value of the "visitCount" cookie from the request's cookies and assigns it to the
visitCount
variable. - It renders the "favecolour" view using
res.render()
, passing an object with data to be rendered in the view. The object contains properties such as the title,faveColour
(retrieved from the request's body),colourCode
, andvisitCount
.
Once you pick a colour you should see the cookies in the Chrome Developer console.
By deleteing the cookies from the Chrome Developer console you can see the effect on the display, ie setting the counter back to 1 and/or the colour back to red.
Deleting a Cookie
The /reset
route will call the resetController
that uses the res.clearCookie
to remove th cookies, replicated the deletion of the cookies through the console.
Persistent Cookies
To demonstrate how the cookies are stored in the browser, open and close the browser window to see the cookie data is retained. Alternatively, open a different browser to see how the cookies have not yet been set (as the cookies are individual to each browser).
Cookies on there own will not provide a secure enough login system, so we next need to look at the concept of sessions.
Next: Sessions