Пишем web на Python3, разрабатываем логику входа в сервис

newbie

Опубликован:  2019-03-04T07:40:40.243618Z
Отредактирован:  2019-03-05T10:45:41.656269Z

Продолжаем работу над проектом selfish. В предыдущем выпуске блога я определил в приложении модель пользователя и создал первого пользователя приложения, и сейчас в арсенале приложения имеются все необходимые атрибуты и инструменты для определения логики входа пользователя в сервис. Этот обзор будет посвящён разработке этой части приложения и построению соответствующей функции представления.

Страница входа в сервис должна давать возможность пользователю приложения вводить свой логин и пароль и отправлять эти данные на сервер, подобный функционал обычно реализуется с помощью определённой совокупности управляющих функциональных элементов, которую обычно называют формой. Форма - это пользовательский интерфейс отображаемый на стороне клиента, посредством которого вводятся и отсылаются на сервер пользовательские данные.

На сервере введённые в форму данные соответствующим образом обрабатываются и проверяются, после чего программа выполняет с этими данными определённые действия. Объект, при помощи которого серверная часть web-приложения обрабатывает форму обычно так и называют - форма.

Для работы с формами я буду использовать ещё один сторонний пакет, который необходимо установить в виртуальное окружение selfish. Запускаю терминал, вхожу в базовый каталог selfish и активирую виртуальное окружение.

cd ~/workspace/selfish
source venv/bin/activate

Устанавливаю в виртуальное окружение два дополнительных пакета.

pip install Flask-WTF validate-email

doySZbG79E.png

Flask-WTF - это расширение Flask, дающее возможность разрабатывать объекты форм с минимальными затратами времени и сил, а с помощью пакета validate-email я получу возможность определять, является ли введённая пользователем строка адресом электронной почты. Логика входа в сервис будет использовать эти два пакета и их функционал, а также установленный и настроенный ранее пакет Flask-Login.

Как обычно, для интеграции Flask-WTF в код selfish потребуется дополнительная конфигурация приложения, но сначала я создам новую подпрограмму, в которой будет реализована система авторизации приложения. Создаю каталог этой подпрограммы и в этом каталоге новые файлы.

mkdir selfish/auth
touch selfish/auth/__init__.py
touch selfish/auth/views.py
touch selfish/auth/forms.py

N3qzIBVjCq.png

Открываю файл selfish/auth/__init__.py и даю этому файлу следующий код.

from flask import Blueprint

auth = Blueprint('auth', __name__)

from . import views

Для реализации логики входа в сервис мне потребуется новая функция представления, которую я создам в файле selfish/auth/views.py, на текущем этапе эта функция представления пока не будет делать ничего особенного.

from . import auth


@auth.route('/login')
def login():
    return 'Сайт в стадии разработки.'

Открываю файл selfish/__init__.py и делаю следующие правки кода в нём.

ldHSluQOyN.png

Открываю файл config.py и дописываю ещё одно свойство классу Development.

lNeLGKleQ6.png

Таким образом, у приложения selfish появилась csrf-защита сессии, новая подпрограмма auth и в ней функция представления login, зарегистрированная в логин-менеджере. Поскольку csrf-защита предполагает, что в рамках приложения появился новый тип ошибок исполнения, ещё один обработчик ошибок следует определить в файле selfish/main/errors.py.

9Io5LN1dQN.png

Теперь всё готово к тому, чтобы создать первую форму приложения, которая будет отвечать за ввод пользователем логина и пароля на странице входа в сервис, и обработку введённых данных на стороне сервера. Открываю в редакторе файл selfish/auth/forms.py и создаю в нём первую форму.

yvvXGpmjlO.png

Моя форма для входа пользователя в сервис содержит следующие поля:

  • поле для ввода логина, логином может быть псевдоним пользователя или его зарегистрированный адрес электронной почты;
  • поле для ввода пароля;
  • поле с флажком, сообщающее серверу нужно ли хранить сессию пользователя;
  • поле submit - кнопка, с помощью которой пользователь может отослать заполненную форму на сервер.

Два первых поля формы (login и password) имеют параметры валидации введённых пользователем данных, посредством которых эти данные будут проходить проверку на сервере. Поле с флажком определяет два возможных значения: True или False, а последнее поле формы на стороне клиента будет представлено управляющей кнопкой с заданным текстом.

Теперь в арсенале приложения есть всё необходимое, чтобы определить логику входа пользователя в сервис, а также логику выхода из сервиса и логику, исполняемую в момент каждого нового отправленного на сервер запроса пользователя. Начнём с логина. Модифицирую функцию преставления login в файле selfish/auth/views.py.

68uKgjH1VS.png

Рассмотрим чуть более детально, что же происходит на сервере, когда пользователь заходит на страницу входа в сервис. Следует обратить внимание, что теперь функция представления login принимает два вида HTTP-запросов: метод GET и метод POST. Если от клиента поступает запрос по методу GET, то в функции представления выполняются только следующие строки:

    if current_user.is_authenticated:
        return redirect(url_for('main.show_index'))
    form = LoginForm()
    form.login.data = ''
    return render_template('auth/login.html', form=form)

В результате чего на соответствующей странице браузера будет рендериться заданный шаблон - auth/login.html. Если пользователь заполнит форму на этой странице и нажмёт соответствующую кнопку для отправки формы, то браузер отправит на сервер по этому же адресу HTTP-запрос по методу POST и на сервере в функции представления login будет исполнен код в блоке:

    if form.validate_on_submit():
        ...

В соответствии с введёнными пользователем данными из базы данных будет отфильтрован пользователь по адресу электронной почты или псевдониму пользователя, в зависимости от того, что ввёл пользователь в форму. Затем будет проверен пароль пользователя и осуществлён вход.

Создаю шаблон для этой функции представления.

mkdir selfish/templates/auth
touch selfish/templates/auth/login.html

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

NUPw05Fs1R.png

SlpCH48VOH.png

Это значит, что тестировать разработанную логику я буду уже после создания шаблона. Создание шаблона для данной функции представления имеет ряд характерных особенностей, это процесс я опишу в деталях в следующем выпуске блога. А пока создам функцию представления для выхода пользователя из сервиса и определю код, который будет исполняться вместе с каждым поступившим от пользователя HTTP-запросом. В файле selfish/auth/views.py дописываю ещё две функции.

s15ZwETkZ2.png

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

Вторая функция - logout даёт возможность пользователю выйти из сервиса, и таким образом прервать авторизованную сессию.

Цель текущего этапа разработки selfish полностью достигнута, протестировать и отладить разработанный функционал я смогу уже только после разработки шаблона для функции представления auth.login, чем и займусь в следующем выпуске блога, где мне опять предстоит работать с frontend приложения, или иначе с клиентской частью приложения. Текущее состояние кода проекта можно увидеть в моём профиле на gitlab.com. Продолжение следует...

Комментарии: