我目前正在开发一个在旧 Symfony 版本上运行的旧版 API(2.8 正在升级到 3.4)。
该应用程序有两个“主要”PHP 入口点:app_dev.php
和 app.php
。 _dev
端点仅应在开发环境中使用,但在旧的生产应用程序中使用不正确。
我们可以轻松修改 API 以避免暴露此文件(并且已经成功完成),但是,我们无法轻松更新连接到 API 的某些应用程序。例如,某些应用程序仍在尝试使用 https://domain/app_dev.php/the/path
进行连接。
作为临时解决方案,在我们努力修复使用 API 的应用程序时,我们希望将 https://domain/app_dev.php/the/path
重写为 https://domain/app.php/the/path
或者更好的是 https://domain/the/path
。 我们相信重写是正确的选择,但也许我们不正确?
我们有 NGINX 的当前配置:
## nginx.conf user www-data; worker_processes auto; worker_rlimit_nofile 65535; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 4096; } http { server_tokens off; include /etc/nginx/mime.types; default_type application/octet-stream; # log_format must come before access_log! log_format main '$remote_addr - $remote_user [$time_local] "$request" $status ' '$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; client_max_body_size 50M; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; large_client_header_buffers 4 16k; include /etc/nginx/conf.d/*.conf; }
## php-prod.conf upstream php { server 127.0.0.1:9000; } server { listen 80; client_max_body_size 50M; client_body_buffer_size 128k; fastcgi_param REMOTE_USER $remote_user; root /var/www/web; location = /favicon.ico { break; } location / { try_files $uri /app.php$is_args$args; } # Configuration for PHP passthrough on remote / production endpoints location ~ ^/app\.php(/|$) { if ($request_method = OPTIONS ) { add_header Content-Length 0; add_header Content-Type text/plain; add_header Access-Control-Allow-Headers "x-custom-auth, content-type, x-requested-with, authorization, mobile"; add_header Access-Control-Allow-Methods "POST, PUT, PATCH, GET, DELETE"; add_header Access-Control-Allow-Origin "$http_origin"; add_header Access-Control-Max-Age 1728000; return 204; } fastcgi_pass php; fastcgi_read_timeout 3600; fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; # When you are using symlinks to link the document root to the current version of your application, you # should pass the real application path instead of the path to the symlink to PHP FPM. Otherwise, PHP's OPcache # may not properly detect changes to your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126 # for more information). fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $realpath_root; # Prevents URIs that include the front controller. This will 404: http://domain.tld/app.php/some-path # Remove the internal directive to allow URIs like this internal; } # Return 404 for all other php files not matching the front controller. # This prevents access to other php files you don't want to be accessible. location ~ \.php$ { return 404; } error_log /var/log/nginx/error.log; access_log off; }
我尝试将 rewrite /app_dev\.php/(.*) /app.php$1 break;
添加到各个地方,包括主 server
块和 location /
块和似乎无法使重定向正常工作。我尝试过使用 break
和 last
但我只从 API 收到没有内容的 500 响应。
如果我更新 location ~ ^/app\.php(/|$) {
到 location ~ ^/(app|app_dev)\.php(/|$) {
它可以正常工作,所以我知道 API 在 NGINX 背后“工作”。
我应该提到 301 重定向在这里不起作用,因为我还需要重写 POST 请求。然而,我已经将其作为 301 重定向进行了测试,并且得到了预期的结果(但 301 不适用于我们的 POST 请求):
location / { rewrite /app_dev\.php/(.*) / permanent; try_files $uri /app.php$is_args$args; } ... 127.0.0.1 - testCommand [25/May/2023:09:04:31 +0000] "POST /app_dev.php/api/path HTTP/1.0" 301 162 "-" "PostmanRuntime/7.32.2" 172.20.0.1 - testCommand [25/May/2023:09:04:31 +0000] "POST /app_dev.php/api/path HTTP/1.1" 301 162 "-" "PostmanRuntime/7.32.2" "-" 172.20.0.1 - - [25/May/2023:09:04:31 +0000] "GET /api/path HTTP/1.1" 301 162 "https://api.domain.com/app_dev.php/api/path" "PostmanRuntime/7.32.2"
如果我将其设置为中断:
172.20.0.1 - testCommand [25/May/2023:09:08:05 +0000] "POST /app_dev.php/api/path HTTP/1.1" 500 5 "-" "PostmanRuntime/7.32.2" "-" 127.0.0.1 - testCommand [25/May/2023:09:08:05 +0000] "POST /app_dev.php/api/path HTTP/1.0" 500 0 "-" "PostmanRuntime/7.32.2"
如果我将其设置为最后:
172.20.0.1 - testCommand [25/May/2023:09:13:57 +0000] "POST /app_dev.php/api/path HTTP/1.1" 500 5 "-" "PostmanRuntime/7.32.2" "-" 127.0.0.1 - testCommand [25/May/2023:09:13:57 +0000] "POST /app_dev.php/api/path HTTP/1.0" 500 0 "-" "PostmanRuntime/7.32.2"
所以我的问题是如何让这个重写工作,将 https://domain/app_dev.php/the/path
等 URL 重写为 https://domain/app.php /the/path
甚至更好 https://domain/the/path
?
您尝试
重写/app_dev\.php/(.*) /app.php$1 break;
,但break是错误的标志 - 您需要使用最后强>。请参阅rewrite
指令。 p>或者,要重定向 POST 请求,您可以使用 307状态响应,例如:
确保将其放置在
location ~ \.php$
块上方。我注意到
location ~ ^/app\.php(/|$)
块被标记为internal
,这会阻止您的服务器响应的外部请求>/app.php
。这似乎与您问题中的某些陈述相矛盾。