Nginx 成功密码保护 PHP 个文件,但随后提示您下载它们

Nginx sucessfully password protects PHP files, but then prompts you to download them

中,我尝试使用带有 .htpasswd 和正则表达式的 Nginx 密码保护我的 /admin/ 和子文件夹目录。

成功完成,但是现在,在完成密码验证后,Nginx 会提示 "download" php 个文件,而不是简单地加载它们。

注释掉新位置 "authentication" 块时不会发生这种情况。例如,在此代码示例中,PHP 页面加载没有任何问题:

    location / {
            try_files $uri $uri/ =404;
    }

    #location "~^/admin/.*$" {
    #       try_files $uri $uri/ =404;
    #       auth_basic "Restricted";
    #       auth_basic_user_file /etc/nginx/.htpasswd;
    #}

    location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
    }

我如何解决这些(明显冲突的)位置块,使 /admin/ 部分受密码保护,但 php 文件仍然加载?

这个问题是对 how nginx processes a request 的根本误解。基本上,nginx 选择一个位置来处理请求。

您希望 nginx 在需要 auth_basic 的位置块中处理以 /admin 开头的 URI。另外,需要将以.php结尾的URI发送到PHP7.

所以你需要两个 fastcgi 块,一个处理普通 PHP 文件,一个处理受限 PHP 文件。

location directive有多种形式。您已经发现正则表达式位置是有序的,因此您的 location "~^/admin/.*$" 块有效地阻止了 location ~ \.php$ 块看到任何以 /admin 开头并以 .php 结尾的 URI。

一个干净的解决方案是使用嵌套位置块并使用 ^~ 修饰符强制前缀位置优先于正则表达式位置:

location / {
    try_files $uri $uri/ =404;
}

location ~ \.php$ {
    try_files $uri =404;

    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
}

location ^~ /admin/ {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;

    try_files $uri $uri/ =404;

    location ~ \.php$ {
        try_files $uri =404;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
    }
}

请注意 location ^~ 是前缀位置而不是正则表达式位置。

另请注意,fastcgi_split_path_infofastcgi_index 指令在 location ~ \.php$ 块中不是必需的。