Nginx内部位置完全忽略django并允许自由访问

Nginx内部位置完全忽略django并允许自由访问,django,nginx,Django,Nginx,我想在django网站上有一个私人媒体文件夹,只有登录的用户才能访问,因此我知道我应该在django端处理身份验证部分,在nginx端处理文件服务。但是,在下面的内部位置配置示例中,我发现不可能使其正常工作。Nginx完全忽略django(仅适用于内部位置情况)。即使我在我的url.py中没有允许的url,并且我在nginx中将其列为内部位置,它仍然可以供每个人自由访问 我正在发布我的nginx配置,希望有人能发现其中的错误 我的期望是,/internal/文件夹中的所有内容都不会被匿名用户访问

我想在django网站上有一个私人媒体文件夹,只有登录的用户才能访问,因此我知道我应该在django端处理身份验证部分,在nginx端处理文件服务。但是,在下面的内部位置配置示例中,我发现不可能使其正常工作。Nginx完全忽略django(仅适用于内部位置情况)。即使我在我的
url.py中没有允许的url,并且我在nginx中将其列为内部位置,它仍然可以供每个人自由访问

我正在发布我的nginx配置,希望有人能发现其中的错误

我的期望是,
/internal/
文件夹中的所有内容都不会被匿名用户访问,只有django应用程序可以通过
X-Accel-Redirect
标题访问。现在,如果我在一个匿名窗口中转到
/internal/test.png
,它会显示图片

我现在没有发布我的django代码,因为它被nginx忽略了,所以它一定是nginx配置问题

server {
    server_name XXX.XX.XX.XXX example.com www.example.com;

    location = /favicon.ico {
        access_log off;
        log_not_found off;
        alias /home/user/myproject/static/favicon4.ico;
    }
    location /static/ {
        root /home/user/myproject;
    }
    location /media/ {
        root /home/user/myproject;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }

    location /internal/ {
        internal;
        root /home/user/myproject;
    }

    root /home/user/myproject;

    location ~* \.(jpg|jpeg|png|webp|ico|gif)$ {
        expires 30d;
    }

    location ~* \.(css|js|pdf)$ {
        expires 1d;
    }

    client_max_body_size 10M;

    # below in this server block is only my Certbot stuff
}

另外,我将可识别数据交换为X个字符和基本名称。

我在此配置中还有两个问题,我将展示我为使其工作所做的一切。正如Richard Smith所建议的,nginx忽略django的最初问题在于nginx如何选择要使用的位置块

从中我们可以看到:

要查找与给定请求匹配的位置,nginx首先检查使用前缀字符串定义的位置(前缀位置)。其中,选择并记住匹配前缀最长的位置。然后按照正则表达式在配置文件中的出现顺序检查正则表达式。正则表达式的搜索在第一次匹配时终止,并使用相应的配置。如果未找到与正则表达式匹配的项,则使用前面记住的前缀位置的配置

而且:

如果最长匹配前缀位置具有“^~”修饰符,则不检查正则表达式

因此,正则表达式(如果可用)将首先被选择<代码>^ ~
前缀前的修饰符使其被选中,而不是正则表达式

我将
location/internal/{
行更改为
location^~/internal/{
,然后每次都会出现404个错误,无论我如何尝试访问这些文件,但至少我知道nginx要访问这个位置

第二个错误是认为我可以使用与文件夹名称相同的url,或者换句话说,我可以将url.py放入文件夹中

path('internal/',views.internal\u media,name='internal\u media')
连同

    location ^~ /internal/ {
        internal;
        root /home/user/myproject;
    }
在我的nginx配置中

我不能。url必须是不同的,因为否则url不会导致django url.py-它仍然会通过nginx导致
/internal/
位置(同样,由于nginx选择位置的方式)

我将我的url.py行改为指向
private
url:

path('private/',views.internal\u media,name='internal\u media')
在views.py文件中,我重定向到
/internal/

def内部_介质(请求,路径):
如果request.user.groups.filter(name='team-special').exists():
response=HttpResponse()
响应['X-Accel-Redirect']='/internal/'+路径
del response['Content-Type']#没有此选项,图像将以文本形式打开
返回响应
其他:
提升许可被拒绝()
aa但这仍然不起作用。每次404个错误。第三个错误是忘记了这两个组合:

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
    location ~* \.(jpg|jpeg|png|webp|ico|gif)$ {
        expires 30d;
    }
现在如果我去了url
/private/test.jpg
nginx不让我去django,因为
location/
的优先级比正则表达式低,所以
location~*
优先,我从来没有到过django。在经历了一段时间的挫败之后,我无意中注意到了这一点,当时我把url错误地放在了匿名中模式。当我转到
/private/test.jp
时,我得到了一个403禁止的错误,而不是404

当我评论完这一点时,它立即开始工作

    location ~* \.(jpg|jpeg|png|webp|ico|gif)$ {
        expires 30d;
    }

    location ~* \.(css|js|pdf)$ {
        expires 1d;
    }
所以现在内部文件工作得很好,但我没有缓存。。。 为了解决这个问题,我修改了我的
/static/
/media/
位置,但我可能不会在这里讨论这个问题,因为这是一个不同的主题。我将发布我的完整nginx配置,它可以工作:)

你可能还想知道的是:

  • ~*
    告诉nginx我们正在编写一个不区分大小写的正则表达式
  • ~
    会告诉nginx我们正在编写一个区分大小写的正则表达式

位于配置底部的正则表达式位置优先。请参阅。请尝试:
location^~/internal/
是!非常感谢您,先生-我成功地出现了下一个错误:D,因为它回答了我发布的问题。您想将其写为答案,以便我可以将其标记为已解决吗?否则,我可以回答我自己的问题并将其记入您的帐户你当然赞成。
server {
    server_name XXX.XX.XX.XXX example.com www.example.com;

    location = /favicon.ico {
        access_log off;
        log_not_found off;
        alias /home/user/myproject/static/favicon4.ico;
        expires 30d;
    }
    location /static/ {
        root /home/user/myproject;
        expires 30d;
    }
    location /media/ {
        root /home/user/myproject;
        expires 30d;
    }
    location ~* \/(static|media)\/\S*\.(css|js|pdf) {
        root /home/user/myproject;
        expires 1d;
    }

    location ^~ /internal/ {
        root /home/user/myproject;
        internal;
        expires 1d;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }

    client_max_body_size 10M;
    
    # certbot stuff
}