@BorisKorobkov
Web developer

Как в Nginx реализовать проверку auth_request самим nginx без скриптов?

Есть высоконагруженный сайт.
1. Есть одна страница аутентификации /login, которая обрабатывается PHP, проверяет логин/пароль (он приходит из обычной html-формы), записывает данные в сессию и куку. Обращений очень мало.
2. Есть одна страница авторизации /auth, которая обрабатывается PHP, проверяет, есть ли у аутентифицированного юзера права доступа к определенной странице. Возвращает код 200 или 403.
3. Весь остальной контент - в виде заранее сгенерированных html-страниц, которые отдаются nginx без PHP. Некоторые страницы общедоступны, некоторые доступны только залогиненным, некоторые только юзерам с определенными правами. Проверка прав доступа осуществляется с помощью nginx модуля auth_request, то есть на каждое обращение к html-странице делается подзапрос к /auth (см. п. 2) с передачей $request_uri, что создает лишнюю нагрузку.

Для оптимизации планирую избавиться от использования PHP в п. 2. Как эту же проверку можно реализовать на самом nginx, то есть как по id юзера ($http_cookie) и запрошенному URI ($request_uri) проверить права с помощью nginx?
Допустим, заранее могу генерировать некоторые файлы с перечнем прав всех юзеров. В каком формате лучше? В голову приходит только структура auth/user/$iserId/$request_uri , то есть проверять наличие файла. Если есть - 200, иначе 403. Но юзеров может быть очень много. Можно всех юзеров записать построчно в файл на каждый URI, но как тогда парсить этот файл из nginx?
Можно эти данные записывать в memcache, но он не гарантирует надежного хранения данных.
Может, в какую-нибудь быструю БД, доступ в которую Nginx может сделать сам?
Или написать демона на java или node.js? Но это потенциально лишняя точка отказа.
  • Вопрос задан
  • 2256 просмотров
Решения вопроса 1
egor_nullptr
@egor_nullptr
Можно сгенерировать конфиг для nginx с использованием map
#auth.conf
map $user_id:$request_uri $allow {
    default 0;
    1234:/path/page1.html 1;
    1234:/path/page2.html 1;
    5678:/path/page1.html 1;
    ...
}

И подключать в конфиге хоста
#host.conf
include "auth.conf";
server {
    listen 80;
    server_name host.org;

    root /path/to/static/pages;

    location / {
        auth_request /_auth;
    }

    location = /_auth {
        if ($allow) {
            return 200;
        }
        return 403;
    }
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
sanchezzzhak
@sanchezzzhak
Ля ля ля...
можно через

session_log_module
mysql_module

смотрим location /auth {
через session модуль получаем ид сессии
смотрим через mysql модуль таблицу сессий
смотрим авторизован или нет.
если нет то на страницу такую...
}

стоит также добавить что в php придется переопределить механизм хранения сессий на БД
через session_set_save_handler
на странице авторизации устанавливаем после авторизации сессию через обычный пых.

это все в теории.
сам модуль mysql под ngnix использовал, впечатления только положительные
еще рекомендую обновить php7+ он быстрей на 50% чем прошлая версия, особенно это чувствуется на работе с массивами.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы