Simple Cookies with Node.js and any frontend JavaScript framework
Tags: node, javascript, beginners, react
Published: 2022-03-26 08:17:21

> Fact: Elite programmers do simple things. It's the idiots who complicate things just to look smart.

## Why another one?

We all have come across blogs to set up HTTP cookies with Node.js and React.js (or any other frontend framework) and let’s be honest it’s hard to find an article with all the information we need to set up our project.

Out there, you find a lot of ifs and buts in configurations so I’ll just tell you what you need to make it work - that’s it. I’ll keep this one short and to the point.

## Agenda

Let’s start with what our setup will look like:

1. Separate configurations for development and production environments; *that’s something missing from all the blogs out there.*

1. Configure the frontend `axios` library to allow the backend to set cookies on the browser.

1. Configure the backend API to set a cookie with the right configurations; *just the ones you need and care about.*

### Assumptions

I am assuming you will be hosting the frontend and the backend API on separate domains. Just to clarify, `api.example.com` and `example.com` are also counted as two separate domains.

## Frontend configurations

On the frontend, I assume you will use a third-party library like [axios](https://www.npmjs.com/package/axios) to make requests to your server. I will advise you to create a new instance of Axios, with all the customised default configurations, and use this instance everywhere else in your project.

### Create Axios instance with custom default configurations

The `.create` function allows you to set different configurations for different types of requests that you want to make to the backend. For example, you could have an Axios instance for making authenticated requests, and another one for making unauthenticated requests.

```javascript
// utils/axios.js

import axios from "axios";

const axiosInstance = axios.create({
  baseURL: "http://api.example.com/api", // optional but recommended
  withCredentials: true, // to allow your API to set cookies on the browser
});

export default axiosInstance;
```

It’s just a better way of doing things 🤷

You’re done with frontend configurations. You can now use this newly created Axios instance to make requests to the backend like you normally would.

For example:

```javascript
// utils/api.js

import axios from "utils/axios";

function fetchProducts() {
  return axios.get("/products/all/");
}
```

Notice, how you don’t have to set the base URL every single time now. You’re welcome :)

## Backend configurations

You will just need to install a single library to your project - [CORS](https://www.npmjs.com/package/cors).

### Environment variables

Create an environment variable to store the frontend URL. If you are running the project in the development environment then you might set it to `http://localhost:8000`, or if you are running it in production then it might be `https://example.com`.

```shell
# .env

FRONTEND_URL=http://localhost:8000
```

You can use a third-party library like [dotenv](https://www.npmjs.com/package/dotenv) to load environment variables from the .env file.

### Set up Express app

Configure CORS and default response headers to be able to set cookies on the frontend browser.

```javascript
// index.js

import express from "express";
import cors from "cors";

async function main() {
  const app = express();
  // ...your Express app configurations

  // allow the frontend to make requests to your API
  app.use(cors({
    origin: process.env.FRONTEND_URL,
    credentials: true
  }));

  // set headers for you to be able to set cookies on the browser
  app.use((_, res, next) => {
    res.header("Access-Control-Allow-Origin", process.env.FRONTEND_URL);
    res.header("Access-Control-Allow-Headers", "*");
    res.header("Access-Control-Allow-Credentials", "true");
    next();
  });

  // ...your rest of the configurations

  app.listen(process.env.PORT, () => {
    console.log("App is up and running");
  });
}

main() // again, just a better way of doing things
```

And, that’s all you need to set up cookies on your backend project. You can now start setting cookies in your endpoint responses.

### Set cookies with working configurations

You can use the given format to set cookies in both development and production environments, using the automatically set environment variable `NODE_ENV`.

```javascript
// routes/auth.js

const isInDevelopment = process.env.NODE_ENV === "development";
const cookieConfigs = {
  httpOnly: true,
  sameSite: isInDevelopment ? false : "none",
  secure: isInDevelopment ? false : true,
  maxAge: 365 * 24 * 60 * 60 * 1000, // one year
};

router.post("/signIn/", (req, res) => {
  // ...your own login
  res.cookie("cookie-name", "cookie-value", cookieConfigs);
  res.status(204).send(); // read about HTTP status 204
});
```

## Conclusion

That’s it! No more wandering from one Stackoverflow answer to another in search of workable cookies configurations with Node.js.

Do like the article if you found this helpful, and/or drop a comment if there’s anything I missed or anything you’d like me to cover in another article.

Signing off! 👋