Angular CORS与Nginx

分享于 

9分钟阅读

互联网

  繁體

问题:

我有一个运行serverXYZ的Angular应用程序,一个用于认证的后端tomcat web app,一个Nginx服务器,端口4200上的Angular应用程序,8080上的tomcat应用程序,都在同一主机上。

angular应用程序有一个environment.ts文件(注释的字符串是我的测试之一,请参阅下面的nginx conf):


export const environment = {


 production: false,


// apiUrl: 'http://serverXYZ:444/api'


 apiUrl: 'http://localhost:8080/backend'


};



Nginx conf:


 server {


 listen 444;



 server_name serverXYZ;



 location / {


 proxy_pass http://localhost:4200;



 //websocket


 proxy_set_header HOST $host;


 proxy_set_header X-Real-IP $remote_addr;


 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


 proxy_set_header X-Forwarded-Proto $scheme;


 proxy_pass_request_headers on;


 proxy_http_version 1.0;


 proxy_set_header Upgrade $http_upgrade;


 proxy_set_header Connection "Upgrade";


 proxy_read_timeout 120s;



 if ($request_method = 'OPTIONS') {


 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-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';


 }



 }



 location /api {


 proxy_pass http://localhost:8080/backend;



 if ($request_method = 'OPTIONS') {


 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-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';


 }



 }


}



后端tomcat应用程序在它的web.xml中有这个:


...


<!-- Tomcat built in CORS implementation -->


 <!-- https://tomcat.apache.org/tomcat-7.0-doc/config/filter.html -->


 <filter>


 <filter-name>CorsFilter</filter-name>


 <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>


 <init-param>


 <param-name>cors.allowed.headers</param-name>


 <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>


 </init-param>


 <init-param>


 <param-name>cors.allowed.methods</param-name>


 <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>


 </init-param>


 </filter>


 <filter-mapping>


 <filter-name>CorsFilter</filter-name>


 <url-pattern>/*</url-pattern>


 </filter-mapping>


 <!-- End of built in CORS implementation -->


...



如果我连接到http://serverXYZ:444,则使用我的计算机,打开浏览器,并显示所描述的conf,该应用程序显示但我在身份验证时收到CORS错误(CORS请求失败)。


答案1:

在内部完成的唯一100%安全的事情是:


return ...;


rewrite ... last;



对于大多数情况下,这过于严格,通常可以在Nginx指令中安全地使用,但是,使用包括add_header在内的任何其他指令实际上是不安全的,并且可能导致不可预测的结果。以下是我如何编写这样的配置:


map $request_method $route {


 GET main;


 POST main;


 OPTIONS options;


 default invalid;


}



map $request_method $api {


 GET api;


 POST api;


 OPTIONS options;


 default invalid;


}



server {


 listen 444;


 server_name serverXYZ;



 location / {


 try_files /dev/null @$route;


 }



 location /api {


 try_files /dev/null @$api;


 }



 location @main {


 # websocket conntection setup


 proxy_set_header HOST $host;


 proxy_set_header X-Real-IP $remote_addr;


 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


 proxy_set_header X-Forwarded-Proto $scheme;


 proxy_pass_request_headers on;


 proxy_http_version 1.0;


 proxy_set_header Upgrade $http_upgrade;


 proxy_set_header Connection "Upgrade";


 proxy_read_timeout 120s;


 # pass the request


 proxy_pass http://localhost:4200;


 # add response CORS headers


 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';


 }



 location @api {


 # transform the URI 


 rewrite ^/api(.*) /backend$1 break;


 # pass the request


 proxy_pass http://localhost:8080;


 # add response CORS headers


 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';


 }



 location @options {


 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-Max-Age' 1728000;


 add_header 'Content-Type' 'text/plain; charset=utf-8';


 add_header 'Content-Length' 0;


 return 204;


 }



 location @invalid {


 # method not allowed


 add_header Allow "GET, POST, OPTIONS";


 return 405;


 }


}





angular  Nginx  CORS