Wordpress 如何使用NGNIX指令将所有请求重定向到一个目录中的文件,但对特定子目录中文件的请求除外?

Wordpress 如何使用NGNIX指令将所有请求重定向到一个目录中的文件,但对特定子目录中文件的请求除外?,wordpress,nginx,Wordpress,Nginx,我有一个wordpress网站,我们想在那里控制对媒体库中文件的访问。这意味着非登录用户需要无法访问/uploads/目录中的所有文件,只有一个子目录/uploads/public/除外。在我的站点的根目录中有一个名为auth.php的文件,它执行实际的权限检查。目前,/public/目录中的文件没有例外。此外,在本地ngnix环境中,在my site.conf.hbs文件的server{}块中添加此指令时,似乎不会调用auth.php。以下是我的site.conf.hbs文件的内容。下面是我的

我有一个wordpress网站,我们想在那里控制对媒体库中文件的访问。这意味着非登录用户需要无法访问
/uploads/
目录中的所有文件,只有一个子目录
/uploads/public/
除外。在我的站点的根目录中有一个名为auth.php的文件,它执行实际的权限检查。目前,
/public/
目录中的文件没有例外。此外,在本地ngnix环境中,在my site.conf.hbs文件的
server{}
块中添加此指令时,似乎不会调用auth.php。以下是我的site.conf.hbs文件的内容。下面是我的指示:

upstream php {
  {{#each fastcgi_servers}}
  server {{this}};
  {{/each}}
}

server {
    listen {{port}};
    root   "{{root}}";

    index index.php index.html index.htm;

    #
    # Generic restrictions for things like PHP files in uploads
    #
    include includes/restrictions.conf;

    #
    # Gzip rules
    #
    include includes/gzip.conf;

    #
    # WordPress Rules
    #
    {{#unless site.multiSite}}
    include includes/wordpress-single.conf;
    {{else}}
    include includes/wordpress-multi.conf;
    {{/unless}}

    #
    # Forward 404's to WordPress
    #
    error_page 404 = @wperror;
    location @wperror {
        rewrite ^/(.*)$ /index.php?q=$1 last;
    }

    #
    # Static file rules
    #
    location ~* \.(?:css|js)$ {
        access_log        off;
        log_not_found     off;
        add_header        Cache-Control "no-cache, public, must-revalidate, proxy-revalidate";
    }

    location ~* \.(?:jpg|jpeg|gif|png|ico|xml)$ {
        access_log        off;
        log_not_found     off;
        expires           5m;
        add_header        Cache-Control "public";
    }

    location ~* \.(?:eot|woff|woff2|ttf|svg|otf) {
        access_log        off;
        log_not_found     off;

        expires           5m;
        add_header        Cache-Control "public";

        # allow CORS requests
        add_header        Access-Control-Allow-Origin *;
    }

    #
    # PHP-FPM
    #
    location ~ \.php$ {
        try_files $uri =404;

        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        fastcgi_param   QUERY_STRING            $query_string;
        fastcgi_param   REQUEST_METHOD          $request_method;
        fastcgi_param   CONTENT_TYPE            $content_type;
        fastcgi_param   CONTENT_LENGTH          $content_length;

        fastcgi_param   SCRIPT_FILENAME         $document_root$fastcgi_script_name;
        fastcgi_param   SCRIPT_NAME             $fastcgi_script_name;
        fastcgi_param   PATH_INFO               $fastcgi_path_info;
        fastcgi_param   PATH_TRANSLATED         $document_root$fastcgi_path_info;
        fastcgi_param   REQUEST_URI             $request_uri;
        fastcgi_param   DOCUMENT_URI            $document_uri;
        fastcgi_param   DOCUMENT_ROOT           $document_root;
        fastcgi_param   SERVER_PROTOCOL         $server_protocol;

        fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;
        fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;

        fastcgi_param   REMOTE_ADDR             $remote_addr;
        fastcgi_param   REMOTE_PORT             $remote_port;
        fastcgi_param   SERVER_ADDR             $server_addr;
        fastcgi_param   SERVER_PORT             $server_port;
        fastcgi_param   SERVER_NAME             $host;

        fastcgi_param   HTTPS                   $fastcgi_https;

        fastcgi_param   REDIRECT_STATUS         200;

        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_pass php;
        fastcgi_buffer_size      64k;
        fastcgi_buffers          32 32k;
        fastcgi_read_timeout     1200s;

        proxy_buffer_size        64k;
        proxy_buffers            32 32k;
        proxy_busy_buffers_size  256k;
    }

    # Protect all uploads:
    if (-e $request_filename){
        rewrite ^/wp-content/uploads/(.*)$ /auth.php?file=$1 break;
    }
}
如果有帮助的话,下面是我的auth.php文件中的第一段代码,我现在使用它来确保我们甚至可以访问auth.php:

<?php

    header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
    define('WP_USE_THEMES', false);
    require_once('wp-load.php');

    wp_die('We made it to auth.php');

Nginx将选择更具体的前缀
位置
,因此要捕获
/wp content/uploads/
,但排除
/wp content/uploads/public/
,可以使用两个前缀位置

例如:

location ^~ /wp-content/uploads/ {
    if (-e $request_filename){
        rewrite ^/wp-content/uploads/(.*)$ /auth.php?file=$1 last;
    }
}
location ^~ /wp-content/uploads/public/ {
    log_not_found     off;
    expires           5m;
    add_header        Cache-Control "public";
}
有必要使用
^
以避免其他
位置
块(静态文件规则)优先(有关详细信息,请参阅)。它还阻止将PHP文件上载到服务器并执行它们

if
块阻止
/auth.php
接收对不存在的文件的请求。
rewrite…last
是将控制权传递给
location~\.php$
所必需的。有关详细信息,请参阅


第二个
location
块包含公用文件夹的适当缓存控制规则。

添加两个
location
块,并将此代码放在其中一个块中。另外,您需要将
break
更改为
last
,否则PHP文件将被下载。您好@RichardSmith,谢谢您的建议,但我有几个问题。1) 我认为需要下载PHP文件,以便在图像不在
/uploads/public/
内时在该图像url上收到登录提示。我在另一个使用.htaccess-2)的网站上也有类似的功能,你能给我一个使用location实现这一功能的代码示例吗?不幸的是,我基本上不了解nginx指令。3) 我不需要专门的规则来排除
/public/
?感谢您的帮助您现有的配置是什么样子的?
服务器
块的内容会很好,这样我们就可以看到还有哪些
位置
块。请编辑问题以添加它,然后我们可以提出更详细的建议。我已经添加了本地测试站点的配置文件的内容。谢谢您,但不幸的是,在我的site.conf.hbs文件中的
server{}
块底部添加该文件后,我的测试站点上没有发生任何事情。你对我应该尝试什么或者我应该补充什么细节有什么想法吗?作为补充说明,如果这最终奏效,我保证明天会对这个问题给予奖励并给你分数。检查
nginx-T
(大写
T
)以确保nginx看到正确的配置。检查访问日志和错误日志,确保请求到达服务器。注释掉
log\u not\u found
语句,以便实际看到错误。使用
curl
进行测试,以避免基于浏览器的副作用。结果证明,我需要停止并重新启动我的网站,以便这些规则生效(我正在为本地wordpress开发人员使用名为“Local”的软件)。我明天会回来给你一笔赏金,并记下你的答案是否正确。非常感谢你的帮助。