How to add cors protection to an express application

Published on January 17, 2019

Cors protection is a recommended security configuration for any api. It protects your customers from unexpected attacks by blocking websites you haven’t approved.

If you have a devOps team they will handle this for you. But if you are a single maker with an application on Heroku and front end on Netlify you need to implement this yourself.

Like most things in express, there’s a package you can install to add cors protection to your application and with a tiny bit of configuration you’ll be set.

First install the package (https://www.npmjs.com/package/cors)

> yarn add cors

Add a new file to your application in /middleware

import cors from 'cors'

const starterCorsProtection = () => {
  const whitelist = getList()
  const corsOptions = {
    credentials: true,
    optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
    origin: whitelist,
  }

  return cors(corsOptions)
}

const getList = (): string[] => {
  const corsSetting = process.env.CORS_ALLOWED_HOSTS || ''
  return corsSetting.split(',')
}

export default starterCorsProtection

Here I have a getList() method that checks your environment for a list of urls to allow.

The environment setting (in .env file) looks like this for my local host for example.

CORS_ALLOWED_HOSTS="http://localhost:3000, https://localhost:3000"

It might look like this for production

CORS_ALLOWED_HOSTS="https://www.darraghoriordan.com"

The cors() method takes an options object and the configuration is as follows.

  • “credentials: true” sets the Access-Control-Allow-Credentials header. This lets us use credentials on ajax requests.
  • “optionsSuccessStatus: 200” helps cors works on more devices.
  • “origin: whitelist” sets the list of allowed urls to the list we set on getList().

Now import the starterCors in your express configuration. Here I use it on every route with “app.use(starterCors);” You also need to specifically use it in the options methods so DELETE requests work.

const starterCors = starterCorsConfiguration()
app.use(starterCors)
app.options('*', starterCors)

You can see this in action on my starter source code @ https://gitlab.com/darragh.oriordan/starter/tree/master

Darragh ORiordan

Hi! I'm Darragh ORiordan.

I live and work in Sydney, Australia enjoying the mountains and the ocean.

I build and support happy teams that create high quality software for the web.

Contact me on Twitter!


Sign up for the newsletter

Get new writings, curated tech articles and coding tips!

Read the Privacy Policy.