使用代理传递指令重写 NGINX 无法正常运行
P粉063862561
P粉063862561 2024-01-10 17:32:41
0
1
365

我目前正在开发一个在旧 Symfony 版本上运行的旧版 API(2.8 正在升级到 3.4)。

该应用程序有两个“主要”PHP 入口点:app_dev.phpapp.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 / 块和似乎无法使重定向正常工作。我尝试过使用 breaklast 但我只从 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?

P粉063862561
P粉063862561

全部回复(1)
P粉642920522

您尝试重写/app_dev\.php/(.*) /app.php$1 break;,但break是错误的标志 - 您需要使用最后强>。请参阅rewrite指令。 p>


或者,要重定向 POST 请求,您可以使用 307状态响应,例如:

location ~ ^/app_dev\.php(/|$) {
    return 307 /app.php$is_args$args;
}

确保将其放置在 location ~ \.php$ 块上方。

我注意到 location ~ ^/app\.php(/|$) 块被标记为 internal,这会阻止您的服务器响应 的外部请求>/app.php。这似乎与您问题中的某些陈述相矛盾。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!