Is it possible to override the 'Access-Control-Allow-Origin' header on the reverse proxy backend?

1. Caddy version (caddy version):

v2.2.1 h1:Q62GWHMtztnvyRU+KPOpw6fNfeCD3SkwH7SfT1Tgt2c=

2. How I run Caddy:

a. System environment:

Ubuntu 20.04 LTS x64, Docker version 19.03.8, Docker-compose version 1.25.0

b. Command:

I run caddy with docker-compose. Please refer to the config below.

c. Service/unit/compose file:

version: '3'

services: 
    # caddy
    caddy:
        image: caddy:latest
        ports:
            - "8848:80"
        volumes:
            - ${CONFIG_PATH}:/etc/caddy/Caddyfile
        environment:
            - DOMAIN
            - BACKEND
        logging:
            driver: "json-file"
            options:
                max-size: "1m"
                max-file: "10"

d. My complete Caddyfile or JSON config:

http://{$DOMAIN} {
    @options {
        method OPTIONS
    }
    header {
        Access-Control-Allow-Origin *
        Access-Control-Allow-Credentials true
        Access-Control-Allow-Methods *
        Access-Control-Allow-Headers *
    }
    reverse_proxy {$BACKEND}
    # to handle pre-flight options request
    respond @options 204
}

3. The problem Iā€™m having:

chrome is giving me this error on requests (like in this post):
'Access-Control-Allow-Origin' header contains multiple values '*, *'

4. Error messages and/or full log output:

Access to XMLHttpRequest at {site} has been blocked by CORS policy: 
The 'Access-Control-Allow-Origin' header contains multiple values '*, *', 
but only one is allowed.

5. What I already tried:

Iā€™m designing the frontend for an existing spring app, and CORS is required in this case. Adding CORS to an existing backend is something easy to do with caddy, however, this time chrome is giving me this error message: 'Access-Control-Allow-Origin' header contains multiple values '*, *'

Admittedly, there would be no need to set Access-Control-Allow-Origin in caddyfile if the backend is already doing so. But the problem is, only a few of the backend apis are responding with the CORS header. (letā€™s say, the /api/foo/bar responses with Access-Control-Allow-Origin, while /api/a/b does not) Locating which of these URLs are carrying the header is a bit painstaking, and hard-coding them in the caddyfile lacks flexibility.

As described in caddy docs, the default behaviour of setting a header directive is to ā€œoverwrite any existing field of the same nameā€. However the header is not doing this job in this case (more like appending to it).

Are there any caddyfile directives that override the ā€˜Access-Control-Allow-Originā€™ header on the reverse proxy? Thank you.

6. Links to relevant resources:

Please upgrade to v2.4.6!

Yeah ā€“ you can use the header_down subdirective of reverse_proxy to remove the headers from the response to avoid the duplicates. (Sorry ā€“ just on my phone otherwise Iā€™d type out an example).

You may need to turn on defer on your header directive as well to make sure the new header values are set after proxying, after the others are removed.

1 Like

Thanks! Iā€™ll give it a shot.

Having no trouble yet with the config below:

http://{$DOMAIN} {
    @options {
        method OPTIONS
    }
    header {
        Access-Control-Allow-Origin *
        Access-Control-Allow-Credentials true
        Access-Control-Allow-Methods *
        Access-Control-Allow-Headers *
        defer
    }
    reverse_proxy shuwashuwa:8848 {
        header_down -Access-Control-Allow-Origin
    }
    respond @options 204
}

Thanks!

2 Likes

This topic was automatically closed after 30 days. New replies are no longer allowed.