首頁  >  問答  >  主體

使用代理傳遞指令重寫 NGINX 無法正常運作

我目前正在開發一個在舊 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粉063862561P粉063862561257 天前320

全部回覆(1)我來回復

  • P粉642920522

    P粉6429205222024-01-11 14:13:15

    您嘗試重寫/app_dev\.php/(.*) /app.php$1 break;,但break是錯誤的標誌- 您需要使用<强>最後。請參閱rewrite指令


    或者,要重定向 POST 請求,您可以使用 307狀態回應,例如:

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

    確保將其放置在 location ~ \.php$ 區塊上方。

    我注意到location ~ ^/app\.php(/|$) 區塊被標記為internal,這會阻止您的伺服器回應 的外部請求>/app.php。這似乎與您問題中的某些陳述相矛盾。

    回覆
    0
  • 取消回覆