Как ограничить медиафайлы проекта django через nginx без выделенного сервера

Я запускаю проект Django в контейнере docker. Uwsgi - выбранный мною протокол. Nginx действует как обратный прокси.

Я могу ограничить сайты django для пользователей на основе user.is_authenticated(). Я не могу ограничить медиа и статические файлы для не аутентифицированных пользователей, поскольку они обслуживаются непосредственно из файловой системы.

У меня нет второго, выделенного сервера, единственной целью которого является идентификация и аутентификация пользователей. Поскольку у меня уже есть функциональность в рамках моего проекта django, я хочу использовать это.

Моя конфигурация nginx:

events{}

daemon off;


http {
    access_log /dev/stdout;
    error_log /var/log/nginx/error.log;

    upstream django {
        server unix:///tmp/nginx/diplab.sock;
    }

    server {
    listen 8080;

    location = /accounts/check-authenticated {
        internal;
        uwsgi_pass              django;
        proxy_pass_request_body off;
        proxy_set_header        Content-Length "";
        }

    location /static {
        alias /vol/web/static;
        include /etc/nginx/mime.types;
        }

    location /media {
        alias /vol/web/media;
        include /etc/nginx/mime.types;
        auth_request /accounts/check-authenticated;
        auth_request_set $auth_status $upstream_status;
        }

    location / {
        uwsgi_pass django;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        include /etc/nginx/uwsgi_params;
        }
    }
}

Моя Django Установка представления, целью которого является аутентификация пользователя (200) или нет (401).

# urls.py
app_name = 'accounts'
urlpatterns = [
    path('check-authenticated/', views.is_authenticated_view, name="check-authenticated"),
    path('login/', views.UserLoginView.as_view(), name='login'),
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]


# views.py
def is_authenticated_view(request):
    if request.user.is_authenticated:
        return HttpResponse(status=200)
    return HttpResponse(status=401)

Ошибка, которая появляется, находится довольно глубоко в ядре Djangos:

Traceback (most recent call last):
  File "/root/miniconda3/envs/myproject/lib/python3.10/site-packages/django/core/handlers/wsgi.py", line 130, in __call__
    request = self.request_class(environ)
  File "/root/miniconda3/envs/myproject/lib/python3.10/site-packages/django/core/handlers/wsgi.py", line 78, in __init__
    self.method = environ["REQUEST_METHOD"].upper()
KeyError: 'REQUEST_METHOD'

В error.log из nginx показано следующее:

2022/12/06 17:42:27 [error] 194#194: *1 upstream prematurely closed connection while reading response header from upstream, client: 172.19.0.1, server: , request: "GET /media/myname/compound_structures/1cf10238af0.png HTTP/1.1", subrequest: "/accounts/check-authenticated", upstream: "uwsgi://unix:///tmp/nginx/diplab.sock:", host: "127.0.0.1:8080", referrer: "http://127.0.0.1:8080/toolbox/"
2022/12/06 17:42:27 [error] 194#194: *1 auth request unexpected status: 502 while sending to client, client: 172.19.0.1, server: , request: "GET /media/myname/compound_structures/1cf10238af0.png HTTP/1.1", host: "127.0.0.1:8080", referrer: "http://127.0.0.1:8080/toolbox/"

Я пытался добавить REQUEST_METHOD плюс некоторые другие переменные таким образом, но без успеха - все та же ошибка.

location = /accounts/check-authenticated {
    internal;
    uwsgi_pass              django;
    proxy_pass_request_body off;
    proxy_set_header        Content-Length "";
    proxy_set_header        REQUEST_METHOD GET;
    proxy_set_header X-Original-URI $request_uri;
    proxy_set_header X-Original-Remote-Addr $remote_addr;
    proxy_set_header X-Original-Host $host;
    }

Я далеко не эксперт в области nginx и буду признателен за любую помощь! Это подход, который я нашел первым. Я буду рад, если вы порекомендуете мне другой подход, если вы не сможете помочь мне с этим.

Вернуться на верх