Heim  >  Fragen und Antworten  >  Hauptteil

Das Umschreiben von NGINX mithilfe von Proxy-Übermittlungsanweisungen funktioniert nicht ordnungsgemäß

Ich entwickle derzeit eine Legacy-API, die auf einer älteren Symfony-Version läuft (2.8 wird auf 3.4 aktualisiert).

Die Anwendung verfügt über zwei „Haupt“-PHP-Einstiegspunkte: app_dev.phpapp.php_dev Dieser Endpunkt sollte nur in einer Entwicklungsumgebung verwendet werden, wird jedoch fälschlicherweise in älteren Produktionsanwendungen verwendet.

Wir könnten die API leicht ändern, um die Offenlegung dieser Datei zu vermeiden (und haben dies erfolgreich getan), allerdings können wir einige der mit der API verbundenen Anwendungen nicht einfach aktualisieren. Einige Apps versuchen beispielsweise immer noch, eine Verbindung über https://domain/app_dev.php/the/path herzustellen.

Als vorübergehende Lösung, während wir an der Behebung von Anwendungen arbeiten, die die API verwenden, möchten wir https://domain/app_dev.php/the/path 重写为 https://domain/app.php/the/path 或者更好的是 https://domain/the/path in https://domain/app.php/the/path oder besser noch https umschreiben ://domain/the/path. Wir glauben, dass Umschreiben die richtige Wahl ist, aber vielleicht liegen wir nicht richtig?

Wir haben die aktuelle Konfiguration von 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;
}

Ich habe versucht, rewrite /app_dev.php/(.*) /app.php break; 添加到各个地方,包括主 server 块和 location / 块和似乎无法使重定向正常工作。我尝试过使用 breaklast hinzuzufügen, aber ich habe von der API nur eine 500-Antwort ohne Inhalt erhalten.

Wenn ich aktualisiere location ~ ^/app.php(/|$) {location ~ ^/(app|app_dev).php(/|$) { funktioniert es einwandfrei, sodass ich weiß, dass die API hinter NGINX „funktioniert“.

Ich sollte erwähnen, dass 301-Weiterleitungen hier nicht funktionieren, da ich auch die POST-Anfrage neu schreiben muss. Ich habe dies jedoch als 301-Weiterleitung getestet und das erwartete Ergebnis erhalten (aber die 301 funktioniert bei unserer POST-Anfrage nicht):

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"

Wenn ich es auf Unterbrechung stelle:

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"

Wenn ich es auf „Dauer“ stelle:

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"

Meine Frage ist also, wie ich dieses Umschreiben zum Laufen bringe und URLs wie https://domain/app_dev.php/the/path 等 URL 重写为 https://domain/app.php /the/path 甚至更好 https://domain/the/path in https://domain/app.php /the/path oder noch besser https:// domain/ umschreibe. the/path?

P粉063862561P粉063862561257 Tage vor317

Antworte allen(1)Ich werde antworten

  • 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$1$is_args$args;
    }

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

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

    Antwort
    0
  • StornierenAntwort