Maison  >  Questions et réponses  >  le corps du texte

La réécriture de NGINX à l'aide des directives de livraison proxy ne fonctionne pas correctement

Je développe actuellement une ancienne API fonctionnant sur une ancienne version de Symfony (2.8 en cours de mise à niveau vers 3.4).

L'application dispose de deux points d'entrée PHP "principaux" : app_dev.phpapp.php_dev Ce point de terminaison ne doit être utilisé que dans un environnement de développement, mais est utilisé de manière incorrecte dans les anciennes applications de production.

Nous pourrions facilement modifier l'API pour éviter d'exposer ce fichier (et nous l'avons fait avec succès), cependant, nous ne pouvons pas facilement mettre à jour certaines des applications connectées à l'API. Par exemple, certaines applications tentent toujours de se connecter en utilisant https://domain/app_dev.php/the/path.

Comme solution temporaire pendant que nous travaillons sur la correction des applications qui utilisent l'API, nous aimerions réécrire https://domain/app_dev.php/the/path 重写为 https://domain/app.php/the/path 或者更好的是 https://domain/the/path en https://domain/app.php/the/path ou mieux encore < code>https ://domain/le/chemin. Nous pensons que la réécriture est le bon choix, mais peut-être n'avons-nous pas raison ?

Nous avons la configuration actuelle de 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;
}

J'ai essayé d'ajouter rewrite /app_dev.php/(.*) /app.php break; 添加到各个地方,包括主 server 块和 location / 块和似乎无法使重定向正常工作。我尝试过使用 breaklast mais je n'ai reçu qu'une réponse de 500 de l'API sans contenu.

Si je mets à jour location ~ ^/app.php(/|$) {location ~ ^/(app|app_dev).php(/|$) { cela fonctionne bien, donc je sais que l'API "fonctionne" derrière NGINX.

Je dois mentionner que les redirections 301 ne fonctionneront pas ici car je dois également réécrire la requête POST. Cependant, j'ai testé cela en tant que redirection 301 et j'ai obtenu le résultat attendu (mais le 301 ne fonctionne pas pour notre requête 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"

Si je le règle pour interrompre :

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"

Si je le règle pour durer :

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"

Ma question est donc de savoir comment faire fonctionner cette réécriture, en réécrivant des URL comme https://domain/app_dev.php/the/path 等 URL 重写为 https://domain/app.php /the/path 甚至更好 https://domain/the/path en https://domain/app.php /the/path ou encore mieux https:// domain/ le/chemin?

P粉063862561P粉063862561306 Il y a quelques jours366

répondre à tous(1)je répondrai

  • P粉642920522

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

    Vous essayez la 重写/app_dev.php/(.*) /app.php break;,但break是错误的标志 - 您需要使用<强>最后。请参阅rewritecommande.


    Alternativement, pour rediriger une requête POST, vous pouvez utiliser une réponse de statut 307, par exemple :

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

    Assurez-vous de le placer au-dessus du bloc location ~ .php$.

    J'ai remarqué location ~ ^/app.php(/|$) 块被标记为 internal,这会阻止您的服务器响应 的外部请求>/app.php. Cela semble contredire certaines des déclarations de votre question.

    répondre
    0
  • Annulerrépondre