Базовая аутентификация в nginx. Закрываем админку магазина

июль 23 , 2019

На страницах блога мы уже не первый месяц работаем с админками. Сделали простую админку на файлах и пилим админку интернет-магазина на vue.js. И все у нас хорошо, кроме того, что наши админки доступны всему интернету. Для тестового магазина в бложике это гордость, а для реального проекта - наоборот.

Это проблема авторизации в веб-приложениях и рано или поздно программисты с ней сталкиваются. Каждый решает это по-разному. В золотые времена фриланса я уверенно закрывал страницы через body { display: none } и это работало. Сейчас так просто уже не получится, приходится читать гуглы и делать технологии.

Когда задумываешься об авторизации первый раз, то хочется сразу сделать красиво. Форма регистрации и логина, хранение паролей в базе данных, естественно, в зашифрованном виде, подтверждение регистрации письмом на почту с уникальной ссылкой, восстановление и возможность смены пароля. А может даже двухфакторная аутентификация или регистрация через соц сети. Много всего. Любой клиент будет рад таким возможностям, да и самому приятно делать сразу и хорошо.

Но есть момент - не всегда это стоит времени и усилий.

Возможно, вы делаете проекты на готовых CMS или фреймворках, где авторизация уже реализована за нас. Разные modx, drupal и laravel по умолчанию дают все, что я перечислил, и даже больше. Не нужно думать и изобретать свое.

Но иногда приходится делать авторизацию, а для мелкого лендинга не хочется ставить даже modx. Например, на сайте всего одна страница. Клиент хочет сам менять телефон, почту и цены. Ставить CMS? Чот неохота. Да и нужно перейти на тариф повыше, где поддерживаются БД. Вот поди объясни владельцу конторы пластиковых окон, за что платить лишние 30 долларов в год? Он у тебя сайт заказал, а не какие-то там базы данных!

Для таких сложных ситуаций "клиент жлоб, а я ленивый" есть выход - подключаем нашу простую файловую админку и закрываем ее через базовую аутентификацию. Что это вообще такое?

Basic Http Authentification придумали как раз для того, чтобы быстро закрывать сайты или их отдельные разделы от посторонних глаз. Поддерживается эта штука практически всеми браузерами и работает адекватно при условии, что ваш сайт на https. На http-сайтах закрывать админки через basic auth не стоит, потому что логин и пароль передаются в http-заголовках в открытом виде. А значит вас могут поломать злые хакеры.

Сейчас мы рассмотрим, как подключить basic auth на админке интернет-магазина. Работать будем на Linux Mint и nginx. Материал нагуглен здесь


Подключаем basic auth

Общая схема работы такова: создадим файлик .htpasswd с логином и паролем, а в конфигах nginx укажем путь к этому файлику и какой сайт или директорию нужно закрыть. Звучит просто, делается тоже несложно.

Сначала нужно установить утилитки, которые помогут сгенерить .htpasswd

    sudo apt install apache2-utils

Теперь можно уже создать нужный файл

    sudo htpasswd -c /etc/nginx/conf.d/.htpasswd admin

Флажок -c указываем, когда только создаем .htpasswd, /etc/nginx/conf.d/.htpasswd - путь к файлику, а admin - нужный логин.

Эта команда предложит ввести пароль для пользователя admin

    $ sudo htpasswd -c /etc/nginx/conf.d/.htpasswd admin
    New password: 
    Re-type new password: 
    Adding password for user admin

Когда введете пароль, то сгенерится файлик с примерно таким содержимым

    $ cat /etc/nginx/conf.d/.htpasswd 
    admin:$apr1$gpUyBum4$f4EFB4xlnnEsBCjUsm/du0

Это пароль admin_password, никому не рассказывайте.

Дальше идем в конфиги nginx

    sudo nano /etc/nginx/sites-available/w-shop.lc

w-shop.lc, это у меня так смешно называется интернет-магазин. Давайте сначала попробуем закрыть его целиком. В разделе server конфига добавим 2 строки

    auth_basic "Enter password!";
    auth_basic_user_file /etc/nginx/conf.d/.htpasswd;

Тупо строка приветствия и путь к файлу. Полный конфиг у меня получился такой

    server {
        listen   80;

        root /home/sn8/www/webdevkin_shop;
        index index.php index.html index.htm;

        auth_basic "Enter password!";
        auth_basic_user_file /etc/nginx/conf.d/.htpasswd;

        server_name w-shop.lc;

        location / {
            try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        location /admin/api/v1/ {
            try_files $uri $uri/ /admin/api/v1/index.php?q=$uri&$args;
        }

        location ~ \.php$ {
            try_files $uri = 404;
            fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }

Дальше перезапускаем nginx

    sudo service nginx restart

И заходим на любую страницу магазина w-shop.lc. Видим такое окошко. Кстати, у меня сайт на домашнем ноутбуке, естественно, без https. Поэтому хром об этом предпреждает, умница. Your connection is not private.

Basic Authentification

Кстати, если у вас открылся сайт без окошка авторизации, то просто страница сохранилась в кеше браузера. Перезагрузите страницу с Ctrl+Shift+R или Cmd+R и увидите приглашение залогиниться. Работает.


Закрываем отдельную папку

Теперь интереснее. Давайте сам сайт откроем, а закроем только админку. Напомню, она лежит в папке /admin/vue. Чтобы закрыть только эту папку, нужно чуть поправить конфиг nginx. Убрать те 2 строчки выше и добавить новый location

    location /admin/vue/ {
        auth_basic "Enter password!";
        auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
    }

Вот и все. Еще раз перезапускаем nginx, пробуем зайти в сам магазин и админку - видим, что закрыта только админка.

Если вам зачем-то понадобилось добавить нового пользователя с другим паролем, то нужно еще раз вызвать утилиту htpasswd, только без флага -с (create - файл уже создан, второй раз его не создать)

    sudo htpasswd /etc/nginx/conf.d/.htpasswd developer

И не забыть перезапустить nginx. Теперь у нас 2 пользователя.


Плюсы и минусы базовой аутентификации

Из плюсов: простота и нативность реализации. Делается парой команд и обеспечивается средствами браузера.

Из минусов. Первое, не каждый хостинг-провайдер позволит править конфиги веб-сервера. Второе, не гибко. Пользователи добавляются руками, чтобы изменить пароль, нужно пересоздать файлик. Я видел код на php, который вытаскивает логины-пароли из базы и подставляет в basic auth, но не проверял. Думаю, заморачиваться с этим не стоит. Если у вас пользователи добавляются динамически, то все равно вам придется делать обвязку, создавать их, удалять, менять пароли, а это уже близко к полноценной системе авторизации.


Когда стоит использовать basic auth

По мне, ее стоит применять в двух случаях.

Первое, при разработке проекта, чтобы скрыть от посторонних глаз целый сайт или отдельный раздел.

Второе, в простой админке вроде упомянутого примера с лендингом.

Для админки небольшого интернет-магазина basic auth подходит. Для личного кабинета - уже нет. Там работать с пользователями нужно тоньше. Хранить пользователей в базе, реализовывать интерфейс для регистрации, логина/разлогина и изменения-восстановления пароля. Разобраться с механизмом работы сессий и подумать, как безопасно хранить пользовательские данные, а особенно, пароли. Но это уже совсем другая история.

Всем удачи и успешных авторизаций.

Заходите в группу в контакте - https://vk.com/webdevkin
Анонсы статей, обсуждения интернет-магазинов, vue, фронтенда, php, гита.
Истории из жизни айти и обсуждение кода.
Как Вам статья? Оцените!