解决Nginx+Ceph RGW跨域问题

在给吉致气车金融做Ceph驻场顾问时,遇到跨域PUT object到返回CORS的错误,经过抓包和日志分析后,发现是其Nginx的配置问题,记录一下
原始的配置

upstream ceph_radosgw_zone {
        server 10.10.100.101:9999 weight=1 max_fails=2 fail_timeout=5;
        server 10.10.100.102:9999 weight=1 max_fails=2 fail_timeout=5;
}

server {
        listen  80;
        location / {
            proxy_pass http://ceph_radosgw_zone;
            proxy_buffering    off;
            client_max_body_size   0;
        }
}

在这样的配置下,由于通过web中间件进行PUT操作,就会产生如下错误

Access to XMLHttpRequest at 'http://10.10.100.100/cbpdev/2019030210121212?x-amz-acl=public-read&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20190222T073759Z&X-Amz-SignedHeaders=host&X-Amz-Expires=29999&X-Amz-Credential=EDEOOIR47GEQ3W3HGCCN%2F20190222%2Fus-east-1%2Fs3%2Faw' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field lang is not allowed by Access-Control-Allow-Headers in preflight response.

错误写的很明确了,header中需要Access-Control-Allow-Headers就像普通的跨域问题
Nginx中加入对应的header应该就可以解决。

server {
        listen  80;
        location / {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, HEAD, PUT';
            add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

            proxy_pass http://ceph_radosgw_zone;
            proxy_buffering    off;
            client_max_body_size   0;
        }
}

测试发现,普通的GET请求是支持跨域了但在PUT文件是依然反悔跨域错误。经过分析发现PUT过程分为OPTIONS和PUT两个Request Method, 只需要在OPTIONS时解决跨域,PUT method时将Header传入Proxy即可
再次修改

server {
        listen  80;
        location / {
            if ($request_method = 'OPTIONS') {
                add_header Access-Control-Allow-Origin *;
                add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, HEAD, PUT';
                add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
            }
            proxy_pass http://ceph_radosgw_zone;
            proxy_pass_header Server;
            proxy_buffering    off;
            proxy_redirect     off;
            proxy_set_header   Host             $host:$server_port;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            client_max_body_size   0;
        }
}

完美解决