21

I am using a simple nginx instance to proxy REST calls to another server. The purpose of my proxy is to allow the use of cookies for authentication. I have it working, except for one problem. The server providing the REST service is sending the header Access-Control-Allow-Origin *. That header is too permissive for cookie based authentication. I need to replace that header with one that is more restrictive.

Here is a subset of my nginx config:

map $http_origin $cors_header {
    default "";
    "~^https?://[^/]+\.mydomain\.com(:[0-9]+)?$" $http_origin;
}

server {    
    location / {
        proxy_pass https://myrestserver.com/api;
        add_header Access-Control-Allow-Origin $cors_header;
        add_header Access-Control-Allow-Credentials true;
    }
}

My problem is that I end up with two Access-Control-Allow-Origin headers present in my response. How can I replace the header that comes back from the REST server so that only my version of the header is present in the final response?

3 Answers 3

11

The best thing to do would be to change the response on the REST server side, but, assuming you don't have control of the REST server, there is a module for Nginx that can modify headers called ngx_headers_more: https://github.com/openresty/headers-more-nginx-module

You'll have to install the module (this will likely involve building nginx from source and adding the module in ./configure, as described in the github readme). For your specific problem, once you install it you can add this directive in any block

more_set_headers "Access-Control-Allow-Origin: $cors_header"
4
  • You may or may not need to use "more_clear_headers" before "more_set_headers". I do, but not sure if it was me being cautious or actually needing to. Building nginx is pretty easy, I have a guide coming out that includes that soon.
    – Tim
    Jan 25, 2016 at 22:00
  • 2
    You don't actually! As the docs say, more_set_headers "Replaces (if any) or adds (if not any) the specified output headers..." but I doubt the cautious approach adds significant overhead. Jan 25, 2016 at 22:05
  • Good to know :) You're right, I clear some headers like "Server" (for security) and "Pragma" (because it's old) and just set the headers I care about.
    – Tim
    Jan 25, 2016 at 22:08
  • This did work without needing to use more_clear_headers. Thanks! Jan 26, 2016 at 4:48
45

this works without extra nginx modules

proxy_hide_header 'access-control-allow-origin';
add_header 'access-control-allow-origin' '*';
4
  • 2
    I do not get it Aug 23, 2018 at 15:33
  • 3
    @Pierre.Vriens You hide the Access-Control-Allow-Origin that you get back from the server you proxy to with proxy_hide_header and then you add your own custom header with add_header. This answer is the only way to "replace" a header in Nginx as far as I know. Upvote from me!
    – Wilt
    Apr 15, 2019 at 14:54
  • I got proxy_hide_header directive is not allowed here so it is not working for me without further explanations...
    – m13r
    Feb 22, 2022 at 16:18
  • @m13r you cannot put proxy_hide_header inside an if block.
    – Zhang Buzz
    Feb 25, 2022 at 4:05
0

Folllow exe-dealer answer and if you are using php to set header you can make:

# always set a new header
add_header  access-control-allow-origin "*" always;

# remove header that came from php
fastcgi_hide_header access-control-allow-origin;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .