使用 nginx 和 aws 启用 cors 的正确配置是啥?

Posted

技术标签:

【中文标题】使用 nginx 和 aws 启用 cors 的正确配置是啥?【英文标题】:What is the right configuration to enable cors with nginx and aws?使用 nginx 和 aws 启用 cors 的正确配置是什么? 【发布时间】:2019-11-19 16:03:25 【问题描述】:

我正在将我的应用程序迁移到 AWS EC2 实例,它曾经托管在 Hostgator 中并且运行良好,现在我已经设法迁移它,但我遇到了一些与 CORS 错误有关的问题。

我的应用程序是前端的 Angular 6 应用程序,我使用 nginx 部署它。后端托管在 heroku 及其 NodeJs 8.0 Restful API 中

经过数小时的研究后,我发现我必须更改应用程序的服务文件。

一开始是这样的,除了CORS错误外,效果还不错

server      
 listen 80;      
 listen [::]:80;      
 server_name http://your-site-name.com;      
 root /var/www/app-name;   
 server_tokens off;   
 index index.html index.htm;     

 location /          
     # First attempt to server request as file, then         
     # as directory, then fall back to displaying a 404.          
     try_files $uri $uri/ /index.html =404;      
 

然后我尝试了一个我在周围找到的解决方案

location / 
  if ($request_method = 'OPTIONS') 
     add_header 'Access-Control-Allow-Origin' '*';
     add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

     add_header 'Access-Control-Max-Age' 1728000;
     add_header 'Content-Type' 'text/plain; charset=utf-8';
     add_header 'Content-Length' 0;
     return 204;
  
  if ($request_method = 'POST') 
     add_header 'Access-Control-Allow-Origin' '*';
     add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
     add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
     add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
 
  if ($request_method = 'GET') 
     add_header 'Access-Control-Allow-Origin' '*';
     add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
     add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
     add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
  

这不起作用,重新加载我的页面后,我收到 404 not found nginx 错误。下一个解决方案也是如此:

location / 

 # Simple requests
 if ($request_method ~* "(GET|POST)") 
   add_header "Access-Control-Allow-Origin"  *;
 

 # Preflighted requests
 if ($request_method = OPTIONS ) 
   add_header "Access-Control-Allow-Origin"  *;
   add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
   add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
   return 200;
 

....
# Handle request
....

最后我尝试了这个:

 location / 
     dav_methods PUT DELETE MKCOL COPY MOVE;

   # Preflighted requestis
   if ($request_method = OPTIONS) 
     add_header "Access-Control-Allow-Origin" *;
     add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD, DELETE";
     add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
    return 200;
  

  # CORS WHITELIST EVERYTHING
  # This is allowing everything because I am running
  # locally so there should be no security issues.
  if ($request_method = (GET|POST|OPTIONS|HEAD|DELETE)) 
    add_header "Access-Control-Allow-Origin" *;
    add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
  

   try_files $uri $uri/ /index.html$is_args$args;

最后一个解决方案运行良好(意思是,我的应用程序正在加载并且没有出现 404 错误)但它仍然给了我 CORS 错误

是的,我确实在我的后端启用了 CORS,这是我的 server.js 文件:

require('./config/config.js');

//Requires
const express = require('express')
const colors = require('colors')

const bodyParser = require('body-parser')


const app = express();

//Enable cors
app.use(function(req, res, next) 
   res.header("Access-Control-Allow-Origin", "*");
   res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, 
Content-Type, Accept, token");
   res.header("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
 next();
);

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded( extended: false ));
app.use(bodyParser.json());


app.use(require("./routes/index"));


//serve
app.listen(process.env.PORT, () => 
    console.log(`Listening $process.env.PORT. Status:`, 'online'.green)
);

这是我在浏览器控制台中遇到的错误

Access to XMLHttpRequest at 
'https://backend.herokuapp.com/inventory/most_sold' from origin 
'http://front-end-ip' has been blocked by CORS policy: No 'Access-Control- 
Allow-Origin' header is present on the requested resource.

希望大家多多指教

提前致谢

【问题讨论】:

【参考方案1】:

您可以使用 CORS(一个 node.js 包,用于提供 Connect/Express 中间件,可用于通过各种选项启用 CORS),即

通过npm i cors在node.js中安装CORS

在 server.js 文件中:-

const cors = require("cors");

然后设置CORS选项,

const corsoption = origin: true, methods: "GET,HEAD,PUT,PATCH,POST,DELETE", credentials: true, exposedHeaders: ["x-auth-token"] ;

app.use(cors(corsoption));

那么你就不会被CORS政策阻止了。

文档:- cors package

【讨论】:

感谢您的回复,很遗憾,此解决方案不起作用。正如我告诉你的,后端在 Hostgator 上运行良好,没有出现 cors 错误。这就是为什么我认为它与 nginx 服务器文件有关。顺便说一句,错误还是一样的 您是否对 server.js 文件进行了更改并将后端重新托管到 heroku?! 是的,我做了两次,以防万一【参考方案2】:

我在 nginx.conf 上使用 more_set_headers 而不是 add_header 取得了更大的成功:

    more_set_headers 'Access-Control-Allow-Origin:http://www.mydomain.test';
    more_set_headers 'Access-Control-Allow-Methods: POST';

即使没有 Access-Control-Allow-Methods 标头,这也适用于 FF 和 Chromium。

more_set_headers 指令是 HttpHeadersMore 模块的一部分,该模块包含在 nginx 的 nginx-extras flavor 中,您可以使用以下命令将其安装在 ubuntu 16 上:

sudo apt-get install nginx-extras

【讨论】:

以上是关于使用 nginx 和 aws 启用 cors 的正确配置是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 AWS CDK 为 AWS API 网关启用 CORS

nginx、aws 和 cloudflare 的 cors 问题

AWS CDK API Gateway 启用 Cors

使用 NGINX 和 AWS Elastic Beanstalk 配置 CORS

AWS API Gateway + AWS Lambda 中的 CORS

Typescript - AWS CDK 启用 CORS