浏览器给出CORS错误,尽管在Nginx中添加了CORS头

pxy2qtax  于 2023-08-03  发布在  Nginx
关注(0)|答案(1)|浏览(310)

我已经为内部IP 192.168.1.119添加了一个主机条目,作为/etc/hosts中的multiserver.billinghub.net
当我访问 http:multiserver.billinghub.net/test/customer-portal时,它对http://multiserver.billinghub.net/jbilling/api/authentication/authenticate进行内部调用,由于域相同,浏览器不会标记XHR调用。
但是当我使用IP地址而不是域名http://192.168.1.119/test/customer-portal时,内部调用使用的是multiserver.billinghub.net,这被视为CORS请求并被浏览器阻止。
我在后端使用Nginx来反向代理请求,并添加了必要的CORS头来解决上述问题。这是我的nginx配置,灵感来自这个要点评论。

  1. upstream customer-portal {
  2. random two least_conn;
  3. server 192.168.1.119:8087;
  4. server 192.168.1.113:8087;
  5. keepalive 4;
  6. }
  7. upstream jbilling {
  8. hash $binary_remote_addr consistent;
  9. server 192.168.1.119:8080;
  10. server 192.168.1.113:8080;
  11. keepalive 4;
  12. }
  13. map $http_origin $cors_origin_header {
  14. default "";
  15. "~(^|^http:\/\/)(localhost$|localhost:[0-9]{1,4}$)" "$http_origin";
  16. "http://multiserver.billinghub.net" "$http_origin";
  17. "http://192.168.1.119" "$http_origin";
  18. }
  19. map $http_origin $cors_cred {
  20. default "";
  21. "~(^|^http:\/\/)(localhost$|localhost:[0-9]{1,4}$)" "true";
  22. "http://multiserver.billinghub.net" "true";
  23. "http://192.168.1.119" "true";
  24. }
  25. ## Server block with port and redirect config
  26. server {
  27. listen 80 reuseport;
  28. server_name multiserver.billinghub.net;
  29. gzip on;
  30. gzip_types application/xml;
  31. gzip_min_length 1000;
  32. add_header 'Access-Control-Allow-Origin' '$cors_origin_header' always;
  33. add_header 'Access-Control-Allow-Credentials' '$cors_cred' always;
  34. add_header 'Access-Control-Allow-Methods' "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH" always;
  35. add_header 'Access-Control-Allow-Headers' "Accept, Accept-Language, Content-Language, Content-Type, authorization, Origin, Referer, User-Agent, Cache-Control, DNT, If-Modified-Since, Cache-Control, Range, Uuid" always;
  36. add_header 'Access-Control-Expose-Headers' '*' always;
  37. if ($request_method = 'OPTIONS' ) {
  38. return 204 no-content;
  39. }
  40. location /test/customer-portal {
  41. proxy_set_header Host $host:$server_port;
  42. proxy_set_header X-Real-IP $remote_addr;
  43. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  44. proxy_set_header X-Forwarded-Proto $scheme;
  45. proxy_pass http://customer-portal;
  46. # Required for new HTTP-based CLI
  47. proxy_http_version 1.1;
  48. proxy_set_header Connection "";
  49. proxy_request_buffering off;
  50. proxy_buffering off; # Required for HTTP-based CLI to work over SSL
  51. # set client body size to 2M #
  52. client_max_body_size 500M;
  53. }
  54. location /jbilling {
  55. proxy_set_header Host $host:$server_port;
  56. proxy_set_header X-Real-IP $remote_addr;
  57. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  58. proxy_set_header X-Forwarded-Proto $scheme;
  59. proxy_pass http://jbilling;
  60. # Required for new HTTP-based CLI
  61. proxy_http_version 1.1;
  62. proxy_set_header Connection "";
  63. proxy_request_buffering off;
  64. proxy_buffering off; # Required for HTTP-based CLI to work over SSL
  65. # set client body size to 2M #
  66. client_max_body_size 500M;
  67. }
  68. }

字符串
添加上述配置后,我仍然得到一个CORS错误,由于某种原因,我得到了多个值在Access-Control-Allow-Header像这样的

有人能告诉我知道我错过了什么吗?谢啦,谢啦

zd287kbt

zd287kbt1#

TL;DR

感谢我的好朋友Bharath,他建议将add_header指令从server级别移动到location级别,问题得到了解决。
由于重复add_header指令并不美观,所以我创建了一个cors.conf文件,并将其包含在location块中。

这是我的cors.conf文件:

  1. add_header 'Access-Control-Allow-Origin' '$cors_origin_header' always;
  2. add_header 'Access-Control-Allow-Credentials' '$cors_cred' always;
  3. add_header 'Access-Control-Allow-Methods' "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH" always;
  4. add_header 'Access-Control-Allow-Headers' "Accept, Accept-Language, Content-Language, Content-Type, Authorization, Origin, Referer, User-Agent, Cache-Control, DNT, If-Modified-Since, Range" always;
  5. add_header 'Access-Control-Expose-Headers' '*' always;
  6. if ($request_method = 'OPTIONS' ) {
  7. return 204 no-content;
  8. }

字符串

更新nginx配置:(为简洁起见,不包括上游块)

  1. map $http_origin $cors_origin_header {
  2. default "";
  3. "~(^|^http:\/\/)(localhost$|localhost:[0-9]{1,4}$)" "$http_origin";
  4. "http://multiserver.billinghub.net" "$http_origin";
  5. "http://192.168.1.119" "$http_origin";
  6. }
  7. map $http_origin $cors_cred {
  8. default "";
  9. "~(^|^http:\/\/)(localhost$|localhost:[0-9]{1,4}$)" "true";
  10. "http://multiserver.billinghub.net" "true";
  11. "http://192.168.1.119" "true";
  12. }
  13. ## Server block with port and redirect config
  14. server {
  15. listen 80 reuseport;
  16. server_name multiserver.billinghub.net;
  17. gzip on;
  18. gzip_types application/xml;
  19. gzip_min_length 1000;
  20. location /test/customer-portal {
  21. proxy_set_header Host $host:$server_port;
  22. proxy_set_header X-Real-IP $remote_addr;
  23. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  24. proxy_set_header X-Forwarded-Proto $scheme;
  25. proxy_pass http://customer-portal;
  26. # Required for new HTTP-based CLI
  27. proxy_http_version 1.1;
  28. proxy_set_header Connection "";
  29. proxy_request_buffering off;
  30. proxy_buffering off; # Required for HTTP-based CLI to work over SSL
  31. # set client body size to 2M #
  32. client_max_body_size 500M;
  33. include /etc/nginx/cors.conf; # <== included cors-related configurations
  34. }
  35. location /jbilling {
  36. proxy_set_header Host $host:$server_port;
  37. proxy_set_header X-Real-IP $remote_addr;
  38. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  39. proxy_set_header X-Forwarded-Proto $scheme;
  40. proxy_pass http://jbilling;
  41. # Required for new HTTP-based CLI
  42. proxy_http_version 1.1;
  43. proxy_set_header Connection "";
  44. proxy_request_buffering off;
  45. proxy_buffering off; # Required for HTTP-based CLI to work over SSL
  46. # set client body size to 2M #
  47. client_max_body_size 500M;
  48. }
  49. }


PS:* 按照这个ServerFault answer使用ngx_headers_more模块构建Nginx也对我有用。*

为什么我首先在Access-Control-Allow-Origin中获得多个值?

当从customer-portal调用jBilling时,Nginx正在添加所需的CORS origin header,但当调用从上游jBilling -> Nginx -> customer-portal返回时
Nginx再次添加了CORS头,因此该值被重复,因为如果头存在,add_header指令不会覆盖该值。
add_header指令转移到location块时,根据Nginx,我们需要手动设置所有必要的头值。
我仍然觉得使用more_headers模块构建Nginx是解决这个问题的更好方法,因为使用ngx_headers_more模块可以获得更多功能。

更新:

我安装了headers-more-nginx-module并将其加载到我的nginx.conf中,这样我就不必维护一个单独的cors.conf(我在上面创建的那个),并且我可以直接在server级别设置必要的CORS头。
下面是我更新的nginx.conf:

  1. user www-data;
  2. worker_processes auto;
  3. pid /run/nginx.pid;
  4. include /etc/nginx/modules-enabled/*.conf;
  5. # Compiled and added headers_more module https://github.com/openresty/headers-more-nginx-module#installation
  6. load_module /etc/nginx/modules-available/ngx_http_headers_more_filter_module.so;
  7. # number of file descriptors used for nginx
  8. # The limit for the maximum FDs on the server is usually set by the OS.
  9. # If you don't set FDs then OS settings will be used which is by default 2000
  10. worker_rlimit_nofile 100000;
  11. events {
  12. worker_connections 4096;
  13. use epoll;
  14. # multi_accept on;
  15. }
  16. http {
  17. ##
  18. # Basic Settings
  19. ##
  20. sendfile on;
  21. tcp_nopush on;
  22. tcp_nodelay on;
  23. keepalive_timeout 65;
  24. types_hash_max_size 2048;
  25. # server_tokens off;
  26. # server_names_hash_bucket_size 64;
  27. # server_name_in_redirect off;
  28. include /etc/nginx/mime.types;
  29. default_type application/octet-stream;
  30. ##
  31. # SSL Settings
  32. ##
  33. ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
  34. ssl_prefer_server_ciphers on;
  35. ##
  36. # Logging Settings
  37. ##
  38. access_log /var/log/nginx/access.log;
  39. error_log /var/log/nginx/error.log;
  40. ##
  41. # Gzip Settings
  42. ##
  43. gzip on;
  44. ##
  45. # Virtual Host Configs
  46. ##
  47. include /etc/nginx/conf.d/*.conf;
  48. include /etc/nginx/sites-enabled/*;
  49. }


更新nginx配置:

  1. upstream customer-portal {
  2. hash $binary_remote_addr consistent;
  3. server 192.168.1.119:8087;
  4. server 192.168.1.113:8087;
  5. keepalive 4;
  6. }
  7. upstream jbilling {
  8. hash $binary_remote_addr consistent;
  9. server 192.168.1.119:8080;
  10. server 192.168.1.113:8080;
  11. keepalive 4;
  12. }
  13. map $http_origin $cors_origin_header {
  14. default "";
  15. "~(^|^http:\/\/)(localhost$|localhost:[0-9]{1,4}$)" "$http_origin";
  16. "http://multiserver.billinghub.net" "$http_origin";
  17. "http://192.168.1.119" "$http_origin";
  18. }
  19. map $http_origin $cors_cred {
  20. default "";
  21. "~(^|^http:\/\/)(localhost$|localhost:[0-9]{1,4}$)" "true";
  22. "http://multiserver.billinghub.net" "true";
  23. "http://192.168.1.119" "true";
  24. }
  25. ## Server block with port and redirect config
  26. server {
  27. listen 80 reuseport;
  28. server_name multiserver.billinghub.net;
  29. gzip on;
  30. gzip_types application/xml;
  31. gzip_min_length 1000;
  32. # Setting Access-Control Headers
  33. more_set_headers 'Access-Control-Allow-Origin: $cors_origin_header';
  34. more_set_headers 'Access-Control-Allow-Credentials: $cors_cred';
  35. more_set_headers 'Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH';
  36. more_set_headers 'Access-Control-Allow-Headers: Accept, Accept-Language, Content-Language, Content-Type,authorization, Origin, Referer, User-Agent, Cache-Control, DNT, If-Modified-Since, Cache-Control, Range, uuid';
  37. more_set_headers 'Access-Control-Expose-Headers: *';
  38. # Allowing preflight request to pass through
  39. if ($request_method = 'OPTIONS' ) {
  40. return 204 no-content;
  41. }
  42. location /test/customer-portal {
  43. proxy_set_header Host $host:$server_port;
  44. proxy_set_header X-Real-IP $remote_addr;
  45. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  46. proxy_set_header X-Forwarded-Proto $scheme;
  47. proxy_pass http://customer-portal;
  48. # Required for new HTTP-based CLI
  49. proxy_http_version 1.1;
  50. proxy_set_header Connection "";
  51. proxy_request_buffering off;
  52. proxy_buffering off; # Required for HTTP-based CLI to work over SSL
  53. # set client body size to 2M #
  54. client_max_body_size 500M;
  55. }
  56. location /jbilling {
  57. proxy_set_header Host $host:$server_port;
  58. proxy_set_header X-Real-IP $remote_addr;
  59. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  60. proxy_set_header X-Forwarded-Proto $scheme;
  61. proxy_pass http://jbilling;
  62. # Required for new HTTP-based CLI
  63. proxy_http_version 1.1;
  64. proxy_set_header Connection "";
  65. proxy_request_buffering off;
  66. proxy_buffering off; # Required for HTTP-based CLI to work over SSL
  67. # set client body size to 2M #
  68. client_max_body_size 500M;
  69. }
  70. }

展开查看全部

相关问题