
NginxのCORS周りの設定においてリバースプロキシとして使用する場合の情報が少なかったのでメモ。
前提
サーバーの構成はこんな感じ

アプリケーションへのリクエストを捌くために、webサーバーとしてNginxを、アプリケーションサーバーとしてPumaを使っている。
アプリケーションサーバーとして何を使うかは関係なくて、とりあえずNginxがプロキシとして動いている場合を想定。
nginxのconfファイル
The way nginx and its modules work is determined in the configuration file. By default, the configuration file is named nginx.conf and placed in the directory /usr/local/nginx/conf, /etc/nginx, or /usr/local/etc/nginx.
自分の環境の場合は/etc/nginxに設置されているようだった。
~~省略~~
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
gzip on;
gzip_http_version 1.0;
gzip_proxied any;
gzip_min_length 500;
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/xml text/css
text/comma-separated-values
text/javascript application/x-javascript
application/atom+xml;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/sites-enabled/*;
}
見てみるとhttpディレクティブの最後にincludeディレクティブで/etc/nginx/sites-enabled/*;とあり、こちらの設定も読み込んでいることがわかる。
デフォルトのconfファイルにはあまり細かな設定は書かずにincludeしてくるのが良いとのこと。
$ ls -ln /etc/nginx | grep sites drwxr-xr-x 2 0 0 4096 8月 13 20:42 sites-available drwxr-xr-x 2 0 0 4096 8月 5 21:11 sites-enabled
よくみると似たような名前のディレクトリがあるものの、
$ ls -ln /etc/nginx/sites-available/ 合計 12 -rw-r--r-- 1 0 0 2360 8月 13 20:42 hoge.net.conf $ ls -ln /etc/nginx/sites-enabled/ 合計 0 lrwxrwxrwx 1 0 0 35 4月 5 2018 hoge.net.conf -> ../sites-available/hoge.net.conf
片方はシンボリックリンクだった。
どうやらシンボリック側からincludeするのが通例らしい。
includeされている方のconfを見てみると
~~省略~~
server {
listen 80 default_server;
server_name hoge.net;
# ヘルスチェック
location /health {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://hoge-puma;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
~中略~
proxy_pass http://hoge-puma;
}
# 静的ファイル
location ~ ^/(img|assets|cvtest|images|uploads|javascripts|stylesheets|swfs|system)/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
}
大体こんな感じ。
serverディレクティブの中でlocationディレクティブを書いている。
imageなどの静的ファイルはそのままnginxで捌いているが、アプリケーションへのリクエストはpumaに渡していることがわかる。
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
~中略~
proxy_pass http://hoge-puma;
}
今回は特定のパスへのリクエストのみCORSの設定を追加したいので、locationディレクティブを新しく追加するか、location /の中でif文で分岐するかのどちらかになりそう。
CORSの設定を追加
修正すべき箇所がわかったので、実際に設定を追加していく
~~省略~~
server {
listen 80 default_server;
server_name hoge.net;
# ヘルスチェック
location /health {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://hoge-puma;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
~中略~
proxy_pass http://hoge-puma;
}
# ここに追加
location = /fuga {
# CORS
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
add_header Access-Control-Allow-Credentials true;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_pass http://hoge-puma;
}
# 静的ファイル
location ~ ^/(img|assets|cvtest|images|uploads|javascripts|stylesheets|swfs|system)/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
}
最初に追加したヘッダは下記の4つ。
# CORS add_header Access-Control-Allow-Origin "*"; add_header Access-Control-Allow-Methods "POST, GET, OPTIONS"; add_header Access-Control-Allow-Headers "Origin, Authorization, Accept"; add_header Access-Control-Allow-Credentials true;
Access-Control-Allow-Origin...CORSリクエストを許可するクライアントドメインを指定する。どこからでも許可する場合は"*"を指定Access-Control-Allow-Methods...CORSリクエストを許可するHTTPメソッドを指定。OPTIONSについてはプリフライトリクエストに対応
で、一度ここまで設定しただけで検証したところエラーが消えず困っていたところ、
proxy_hide_header 'Access-Control-Allow-Origin';
こちらも必要みたいだった。
参考
NGINX Reverse Proxy and Access-Control-Allow-Origin issue - Stack Overflow