Nginx auth_request: закрыть файлы проверкой доступа
auth_request отправляет внутренний подзапрос перед обработкой основного запроса. Ответ 2xx разрешает доступ, 401 и 403 запрещают, а любой другой статус даёт клиенту 500. Так Nginx проверяет сессию или токен через отдельный сервис и не отдаёт статику или проксированный ресурс без подтверждения.
Проверить доступ перед проксированием
upstream auth_service {
server 127.0.0.1:9001;
}
upstream files_service {
server 127.0.0.1:9002;
}
server {
listen 80;
server_name files.example.com;
location = /_auth {
internal;
proxy_pass http://auth_service/verify;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
location /files/ {
auth_request /_auth;
auth_request_set $auth_user $upstream_http_x_user_id;
proxy_set_header X-User-Id $auth_user;
proxy_pass http://files_service;
}
}Директива internal запрещает обращаться к /_auth снаружи: этот location доступен только как подзапрос. proxy_pass_request_body off и пустой Content-Length не передают тело основного запроса сервису авторизации. Заголовок X-Original-URI помогает проверить, к какому именно пути запрашивается доступ.
auth_request_set сохраняет заголовок из ответа проверки, чтобы передать идентификатор пользователя во внутренний сервис. Не доверяйте входящему заголовку X-User-Id от клиента: перезаписывайте его значением из доверенного ответа, как в примере.
Проверка выполняется на каждый запрос, поэтому сервис авторизации должен отвечать быстро; кешируйте результат в нём, а не в Nginx. Для защищённого location отключите кеширование ответа, если права могут измениться между запросами. Директиву можно ставить в http, server или location; модуль ngx_http_auth_request_module входит в стандартные сборки Nginx, но проверьте его наличие через nginx -V.
Если проверка возвращает 401, клиенту можно показать страницу входа через error_page 401 = @login;. Не добавляйте auth_request в location самой проверки — получится рекурсивный подзапрос.
Документация: ngx_http_auth_request_module.