How to add cors protection to an express application
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