Caddy as a CORS proxy
CORS is a common issue when you are developing a web application. It is a security mechanism that restricts the resources you can access from another domain.
The usual solution is to contact the API provider and ask them to add your domain to the CORS whitelist. However, this is not always possible. For example, if you are using a third-party API, you may not be able to contact the API provider.
In this article, I will show you how to use Caddy as a (local) CORS proxy to bypass CORS issue.
Quick start
Install Caddy
You can install Caddy in many ways, see the official documentation for more details.
On macOS, you can simply run:
brew install caddy
Create a config file (Caddyfile)
Let’s assume that remote API host is https://robwu.nl
, and local proxy we named cors.local
. The Caddyfile
should look like this:
(cors) { header { Access-Control-Allow-Origin "{http.request.header.Origin}" Access-Control-Allow-Credentials true Access-Control-Allow-Methods * Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization } @options { method OPTIONS } @not-options { not method OPTIONS }}
cors.local { log { output file ./caddy-access.log level ERROR } respond @options 204 reverse_proxy @not-options https://cors.local https://robwu.nl { header_up Host {upstream_hostport} header_up -X-Forwarded-Host header_up -X-forwarded-For header_up -X-forwarded-Proto header_down -Access-Control-Allow-Origin } import cors}
Don’t forget to replace robwu.nl
with the actual domain name.
Configure DNS & TLS
In order to be able to use a local custom domain name and HTTPS, you need to configure DNS and TLS.
Add the following line to /etc/hosts
:
Usually you need to use sudo
to edit this file.
127.0.0.1 cors.local
You also need to trust the local CA in order to use HTTPS, run the following command:
caddy trust
Run Caddy
Run Caddy in foreground:
caddy run
or, run Caddy in background:
caddy startcaddy stop
Now you can access the proxied API with CORS headers.
curl -v -H "Origin: http://127.0.0.1:3000" https://cors.local/dump.php
Known issues
- Sometimes, the response from the proxied API has duplicate CORS headers.