CORS在express级别或Nginx级别或两者兼而有之?http和https都需要单独处理吗?

sxissh06  于 2023-11-17  发布在  Nginx
关注(0)|答案(1)|浏览(239)
  1. import { NODE_ENV } from 'common/constants';
  2. export function getAllowedOrigins() {
  3. // https://github.com/expressjs/cors/issues/272#issuecomment-1186236472
  4. let allowedOrigins: string[] = [];
  5. if (NODE_ENV === 'development') {
  6. allowedOrigins = ['http://www.example.local', 'https://www.example.local'];
  7. } else if (NODE_ENV === 'test') {
  8. allowedOrigins = [
  9. 'http://staging.example.com',
  10. 'https://staging.example.com',
  11. ];
  12. } else if (NODE_ENV === 'production') {
  13. allowedOrigins = ['http://www.example.com', 'https://www.example.com'];
  14. }
  15. return allowedOrigins;
  16. }

字符串

  • 我正在尝试使用上述文件在我的node.js express应用程序上设置cors

这是我的Express应用程序文件

  1. ...
  2. const app = express();
  3. app.use(rTracer.expressMiddleware());
  4. app.use(requestLogger);
  5. app.use(
  6. cors({
  7. credentials: true,
  8. origin: getAllowedOrigins(),
  9. }),
  10. );
  11. ...

  • 我的本地开发、测试和生产环境运行在localhost:8000上
  • 我还有一个docker开发,它使用自签名的https证书在nginx后面的API.example.local上运行
  • 我的生产环境最终运行在AWS上,certbot支持nginx后面的https

这就是我在AWS上运行的最终产品nginx.conf文件的样子

  1. # Generated by nginxconfig.io
  2. # See nginxconfig.txt for the configuration share link
  3. user nginx;
  4. pid /tmp/nginx.pid;
  5. worker_processes auto;
  6. worker_rlimit_nofile 65535;
  7. # Load modules
  8. include /etc/nginx/modules-enabled/*.conf;
  9. events {
  10. multi_accept on;
  11. worker_connections 65535;
  12. }
  13. http {
  14. charset utf-8;
  15. sendfile on;
  16. tcp_nopush on;
  17. tcp_nodelay on;
  18. server_tokens off;
  19. log_not_found off;
  20. types_hash_max_size 2048;
  21. types_hash_bucket_size 64;
  22. client_max_body_size 16M;
  23. # MIME
  24. include mime.types;
  25. default_type application/octet-stream;
  26. # Logging
  27. access_log off;
  28. error_log /var/log/nginx/error.log error;
  29. # Limits
  30. limit_req_log_level warn;
  31. limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
  32. # SSL
  33. ssl_session_timeout 1d;
  34. ssl_session_cache shared:SSL:10m;
  35. ssl_session_tickets off;
  36. # Diffie-Hellman parameter for DHE ciphersuites
  37. ssl_dhparam /etc/ssl/certs/dhparam.pem;
  38. # Mozilla Intermediate configuration
  39. ssl_protocols TLSv1.2 TLSv1.3;
  40. ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
  41. # OCSP Stapling
  42. ssl_stapling on;
  43. ssl_stapling_verify on;
  44. resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
  45. resolver_timeout 2s;
  46. # Connection header for WebSocket reverse proxy
  47. map $http_upgrade $connection_upgrade {
  48. default upgrade;
  49. "" close;
  50. }
  51. map $remote_addr $proxy_forwarded_elem {
  52. # IPv4 addresses can be sent as-is
  53. ~^[0-9.]+$ "for=$remote_addr";
  54. # IPv6 addresses need to be bracketed and quoted
  55. ~^[0-9A-Fa-f:.]+$ "for=\"[$remote_addr]\"";
  56. # Unix domain socket names cannot be represented in RFC 7239 syntax
  57. default "for=unknown";
  58. }
  59. map $http_forwarded $proxy_add_forwarded {
  60. # If the incoming Forwarded header is syntactically valid, append to it
  61. "~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*([ \\t]*,([ \\t]*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*)?)*$" "$http_forwarded, $proxy_forwarded_elem";
  62. # Otherwise, replace it
  63. default "$proxy_forwarded_elem";
  64. }
  65. # Load configs
  66. include /etc/nginx/conf.d/*.conf;
  67. # api.ch.com
  68. server {
  69. listen 443 ssl http2 reuseport;
  70. listen [::]:443 ssl http2 reuseport;
  71. server_name www.api.ch.com;
  72. root /var/www/_letsencrypt;
  73. # SSL
  74. ssl_certificate /etc/letsencrypt/live/api.ch.com/fullchain.pem;
  75. ssl_certificate_key /etc/letsencrypt/live/api.ch.com/privkey.pem;
  76. ssl_trusted_certificate /etc/letsencrypt/live/api.ch.com/chain.pem;
  77. # security headers
  78. add_header X-XSS-Protection "1; mode=block" always;
  79. add_header X-Content-Type-Options "nosniff" always;
  80. add_header Referrer-Policy "no-referrer-when-downgrade" always;
  81. add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always;
  82. add_header Permissions-Policy "interest-cohort=()" always;
  83. add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
  84. # . files
  85. location ~ /\.(?!well-known) {
  86. deny all;
  87. }
  88. # security.txt
  89. location /security.txt {
  90. return 301 /.well-known/security.txt;
  91. }
  92. location = /.well-known/security.txt {
  93. alias ~/security.txt;
  94. }
  95. # logging
  96. access_log /var/log/nginx/access.log combined buffer=512k flush=1m;
  97. error_log /var/log/nginx/error.log error;
  98. # reverse proxy
  99. location / {
  100. proxy_pass http://api_server_prod:21347;
  101. proxy_set_header Host $host;
  102. proxy_http_version 1.1;
  103. proxy_cache_bypass $http_upgrade;
  104. # Proxy SSL
  105. proxy_ssl_server_name on;
  106. # Proxy headers
  107. proxy_set_header Upgrade $http_upgrade;
  108. proxy_set_header Connection $connection_upgrade;
  109. proxy_set_header X-Real-IP $remote_addr;
  110. proxy_set_header Forwarded $proxy_add_forwarded;
  111. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  112. proxy_set_header X-Forwarded-Proto $scheme;
  113. proxy_set_header X-Forwarded-Host $host;
  114. proxy_set_header X-Forwarded-Port $server_port;
  115. # Proxy timeouts
  116. proxy_connect_timeout 60s;
  117. proxy_send_timeout 60s;
  118. proxy_read_timeout 60s;
  119. }
  120. # favicon.ico
  121. location = /favicon.ico {
  122. log_not_found off;
  123. }
  124. # robots.txt
  125. location = /robots.txt {
  126. log_not_found off;
  127. }
  128. # gzip
  129. gzip on;
  130. gzip_vary on;
  131. gzip_proxied any;
  132. gzip_comp_level 6;
  133. gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
  134. }
  135. # non-www, subdomains redirect
  136. server {
  137. listen 443 ssl http2;
  138. listen [::]:443 ssl http2;
  139. server_name .api.ch.com;
  140. # SSL
  141. ssl_certificate /etc/letsencrypt/live/api.ch.com/fullchain.pem;
  142. ssl_certificate_key /etc/letsencrypt/live/api.ch.com/privkey.pem;
  143. ssl_trusted_certificate /etc/letsencrypt/live/api.ch.com/chain.pem;
  144. # logging
  145. error_log /var/log/nginx/error.log error;
  146. return 301 https://www.api.ch.com$request_uri;
  147. }
  148. # HTTP redirect
  149. server {
  150. listen 80 reuseport;
  151. listen [::]:80 reuseport;
  152. server_name .api.ch.com;
  153. # logging
  154. error_log /var/log/nginx/error.log error;
  155. # ACME-challenge
  156. location ^~ /.well-known/acme-challenge/ {
  157. allow all;
  158. root /var/www/_letsencrypt;
  159. }
  160. location / {
  161. return 301 https://www.api.ch.com$request_uri;
  162. }
  163. }
  164. }


问题

  • 我需要在允许的来源下分别列出https和http的域吗?
  • 我需要修改nginx.conf文件来处理cors吗?
  • 我需要在生产中包含localhost:8000作为允许的来源吗?
ztmd8pv5

ztmd8pv51#

  • 1.我是否需要在允许的来源下分别列出httpshttp的域名?*

您可以使用regExp,它可以匹配httphttps,并包括subdomain

  1. import { NODE_ENV } from "common/constants";
  2. export function getAllowedOrigins() {
  3. let allowedOrigins;
  4. if (NODE_ENV === "development") {
  5. allowedOrigins = /example\.com$/;
  6. } else if (NODE_ENV === "test") {
  7. allowedOrigins = /staging\.example\.com$/;
  8. } else if (NODE_ENV === "production") {
  9. allowedOrigins = "https://www.example.com"; // for production https prefered
  10. }
  11. return allowedOrigins;
  12. }

字符串

  • 2.我是否需要以任何方式修改我的nginx.conf文件来处理cors?*

不,你不需要它,即使你可以,因为控制在一个地方更好的许多。让表达处理它。

  • 3.我是否需要将localhost:8000包括在生产中允许的原产地?*

绝对不是,生产环境是一个隔离的环境,没有必要包括localhost

展开查看全部

相关问题