circuit

How to Send Cookies from Express to a Front-End Application in Production

How to send cookies from an Express app via express-session package to the frontend in an HTTPS protocol.




In this article, I would be explaining how to send cookies from an Express app via an express-session package to the front end in an HTTPS protocol.

If you have ever tried working with cookies in Express and a front-end application like React, you must have discovered there are quite a number of options you have to consider in different parts of your application while setting up cookies. Setting a single one of those options incorrectly would give you cookie issues. And to make matters worse, error messages are not quite clear.

The first set of options we would be exploring is the secure and *samesite *option in the cookie options. The samesite attribute allows cookies to be set on third-party domains(in this case your front-end application). There are a couple of options here but for this case, it is best to set samesite to “none”, this allows cookies to be set on third-party websites.

For security reasons most browsers require you to set the secure option to true anytime, you set* samesite *to “none” to enforce HTTPS protocol. And hence you must host your application in an HTTPS environment. This means that in a local environment(localhost) that uses an HTTP protocol you might not be able to set cookies in a decoupled application. And as such you must find another alternative maybe proxy.

Above is how your express-session middleware should be set. Notice how the sameSite and secure option is set in the cookie object is set.

Another option to take note of is the trust-proxy option. Most PAAS e.g Heroku makes use of load balancers. Basically, a load balancer is a server that distributes network requests to other servers. Express most times will look at the req.socket.remoteAddress to see if the request is coming from an HTTP or HTTPS connection and the way load balancers most times are set up is to forward requests via HTTP since communications between them and the servers that they forward request to are usually within the same VPC. So Express sees the request coming from an HTTP address that is not secured. But thankfully, we can tell express to look at the x-forwarded header to see where the original request is coming from. This can be done by setting trust proxy to 1. So express sees the front-end IP as the left-most entry in the x-forwarded header.

Setting the trust proxy option to 1 app.set("trust proxy", 1);

Above is how you can set the trust proxy option.

Note: All of this should be done before defining any of your routes.

Now there are is an option we need to cover from our front-end application. Most times when sending a request to a URL, cookies set are automatically sent, however in this case we are sending a request to a web server on another URL, and as such it is required you explicitly tell the package you're using to send the request to send cookies. And in Axios, fetch, and other HTTP client packages this can be done by setting the withCredentials option to true.

Since you are hosting your front-end and back-end application on two different secured(HTTPS) domains. The first issue you usually encounter is the cors issue. A lot of developers usually set up cors to set origin response headers to a wildcard().

Access-Control-Allow-Origin: *

If you set up cors like this in your Express app.use(cors()) it means you are setting the access-control-response-origin header to a wildcard.

Setting up cors to a wildcard creates an issue when setting cookies to a third-party domain(your front end app). This is because most browsers do not allow a server that responds with a wildcard() origin header to set cookies, this was done for security reasons. You must therefore explicitly set the origin, if you are using the cors package this is east by just setting the origin option in the middleware as:

app.use(cors({origin: “https://your-url.com"}))

To know more about cors you can click here, I think MDN did a pretty good job explaining it.

Also due to security reasons, there is one more thing to do on the express app, you must also tell cors to accept credentials by setting the credential options to true. And as such for the cors option this is what it should look like:

This is how your cors option should look like

app.use(
  cors({
    origin: "https://cookiefront.herokuapp.com",
    credentials: true,
  })
);

I have a youtube video where I explained how to set up cookies from an express app to a react front end. In the video, I also explained how you can do this locally and in production. The video is linked below:




Continue Learning