Задать вопрос

Доступ к серверу с СМС-авторизацией через nginx

У нас тут для клиента было необходимо организовать СМС-авторизацию.
У клиента большое веб-приложение к которому доступ осуществляется только с логином и паролем. Но кроме этого клиент захотел сделать еще и авторизацию через СМС. Влезть в приложение и встроить проверку туда возможности нет, да и паранойя клиента ставила задачу так, что без СМС-авторизации доступа к приложению не должно быть совсем. Ну что ж. Раз просят, решили делать.


На сервере поставили nginx и apache. В апаче два виртуальных хоста на разных портах. 88 и 8080. Эти порты на сервере закрыты извне.
nginx висит на порту 80, который как раз единственный открытый.

По умолчанию nginx проксирует все запросы на порт 88. Там лежит наша система СМС-авторизации. Человек вводит логин и пароль, по этой паре наше приложение получает номер телефона, отправляет на этот телефон СМС со случайно сгенерированным кодом. Пользователь получает СМС, вводит код. Наше приложение сравнивает его с тем что было отправлено, если всё ОК, то устанавливает пользователю куку AUTH. В нее устанавливает уникальную строку из 32х абсолютно случайных символа. И кроме этого бросает на диск файлик с таким же именем. После этого обновляет страницу.
Пользователя опять встречает nginx. Он берет куку, смотрит, есть ли такой файлик на диске, и если есть, то проксирует запрос пользователя уже на клиентское приложение. Кука живёт сессию. Пока есть кука, человек пользуется клиентским приложением. Если сессия кончилась, то человека опять встретит наша система авторизации.

Вот кусок конфига nginx, который отвечает за проверку:
set $flag 0;
if (-f /tmp/auth/$cookie_AUTH) {
	set $flag 1;
}
set $folder 'www';
if ($flag = 1) {
	set $folder 'wwwApp';
}
root /home/$folder;
index  index.html index.htm index.php;
location / {
	if ($flag = 1) {
		proxy_pass http://127.0.0.1:8080;
	} proxy_pass http://127.0.0.1:88;
}


Получилось так, что nginx дёргает диск на наличие файла на абсолютно каждом хите. Запрашивается ли js-ка, jpeg или что-либо другое, он всё равно каждый раз проверяет наличие файла. Хотя пользователей и немного, но решили перенести место хранения этих файлов на рам-диск, чтобы уменьшить количество обращений к диску.

С организацией такой авторизации столкнулись первый раз и придумывали велосипед сами :)
Может быть кто посоветует более красивый вариант реализации такой штуки?
Ну и есть ли какие-то прям очевидные минусы данного решения?
  • Вопрос задан
  • 5460 просмотров
Подписаться 6 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
@rozhik
Распишу подробнее.
Итак имеем 2 недостатка 1) лишняя проверка на существование файла. 2) затраты на создание этого флаг файла и очистку.

Идея здесь. Создаём хэш как
$expire = time() + 3600; //Время, на которое даём доступ
$hash = $expire.':'.md5($secret  . $expire); // Вот это шлём в куки значение


Дальше в nginx на луа, перле или модулём делаем
// Это псевдокод
list( $expire, $md5 ) = explode( $cookieValue ); 
if( $cookieValue == $expire.':'.md5($secret  . $expire) && $expire >= time() ) {
  // Авторизированы
} else {
  // Не авторизированы
}

У вышеописаной идеи есть недостаток — нужно либо иногда обновлять куку, либо ставить длинное время жизни сессии. Но обращений к диску нет.
Ответ написан
@rozhik
Есть модуль secure link. Базируется на тривиальной идее. Почитайте о нем. Там подписуется кука на время.
Ответ написан
VasiliyIsaichkin
@VasiliyIsaichkin
Web front/back-end (JS-full stack) app developer
Еще как вариант можно читать данные из memcahe (nginx это умеет штатно) в переменную с помощью модуля eval (www.grid.net.ru/nginx/eval.ru.html‎)
Ответ написан
Ваш ответ на вопрос

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

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