Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Z1411_Tyutterin_Yakov_TP.docx
Скачиваний:
3
Добавлен:
07.01.2025
Размер:
10.83 Mб
Скачать
  1. Реализация проекта

Начнем с BackEnd-части, а именно с регистрации пользователя, чтобы строить систему с этого. Для этого введем контроллер, который будет отвечать за три эндпоинта:

  • Регистрация

  • Аутентификация

  • Логаут (выход из системы)

Также, зная, что наш BackEnd будет работать с отдельным веб-сервисом (FrontEnd), зададим Cross-политику, указав соответствующий адрес сервера в файле конфигурации. Стандартным локальным адресом в случае Angular используется http://localhost:4200/. То есть запросы будем принимать лишь с него. Результат указания его в файле конфигурации зафиксирован на рисунке 2.

Рисунок 2 – Допустимый адрес, с которого будут допускаться запросы

Реализация контроллера представлена на рисунке 3. Для получения адреса на уровне контроллера используется Spel. SpEL — это язык выражений, созданный для Spring Framework, который поддерживает запросы и управление графом объектов во время выполнения. Также важно отметить, что SpEL создан в виде API-интерфейса, позволяющего интегрировать его в другие приложения и фреймворки. Также для представления данных, получаемых от пользователя, введены DTO-классы, реализация которых представлена на рисунках 4-5.

Data Transfer Object (DTO) — один из шаблонов проектирования, используемый для передачи данных между подсистемами приложения.

В отличие от business object или Data Access Object, DTO не должен содержать какого-либо поведения.

Рисунок 3 – Реализация контроллера

Рисунок 4 – Класс DTO для представления данных, полученных от пользователя при аутентификации.

Рисунок 5 – Класс DTO для представления данных, полученных от пользователя при регистрации.

Веб-сервисы между собой общаются по REST. REST (от англ. Representational State Transfer — «передача репрезентативного состояния» или «передача “самоописываемого” состояния») — архитектурный стиль взаимодействия компонентов распределённого приложения в сети.

Это набор правил, как программисту организовать написание кода серверного приложения, чтобы все системы легко обменивались данными и приложение можно было масштабировать.

В широком смысле компоненты в REST взаимодействуют наподобие взаимодействия клиентов и серверов во Всемирной паутине.

В основном, данные будут передаваться в формате json. JSON — это популярный формат текстовых данных, который используется для обмена данными в современных веб - и мобильных приложениях. Кроме того, JSON используется для хранения неструктурированных данных в файлах журналов или базах данных NoSQL, таких как Microsoft Azure Cosmos DB. Многие веб-службы REST возвращают результаты в формате текста JSON или принимают данные в формате JSON.

Классы DTO используются при сериализации-десериализации. В нашем случае при регистрации/аутентификации, данные приходит на Back в виде json, а затем десериализуются в наши классы-DTO, с которыми нам будет удобно работать. Дополнительно, для поддержания валидности данных и описания правил валидации декларативно – используется jakarta.validation, позволяющий с помощью стандартных аннотаций описать основные правила для входных данных, но при необходимости можно всегда написать кастомное решение, что и будет сделано позже.

Также для дальнейшего сохранения данных необходимо создать и подключить базу данных к нашего приложению.

В качестве БД будет использоваться PostgreSQL. Сама она будет развернута в Docker-контейнере. Docker – это программное обеспечение для автоматизации развёртывания и управления приложениями в средах с поддержкой контейнеризации.

Позволяет «упаковать» приложение со всем его окружением и зависимостями в контейнер, который может быть развёрнут на любой Linux-системе с поддержкой контрольных групп в ядре. Результат создания изображения показан на рисунке 6.

Рисунок 6 – Docker image

Также для подключения БД к проекту, необходимо добавить соответствующий драйвер в файл XML для системы сборки Maven. Добавление драйвера представлено на рисунке 7.

Рисунок 7 – Драйвер БД.

Также, так как используется flyway, необходимо добавить соотвествующую зависимость для него, все это представлено на рисунке 8.

Рисунок 8 – Зависимость для flyway.

Теперь необходимо прописать параметры подключения к БД и настроить поведение flyway при запуске. Дополнительно настраиваются некоторые параметры ORM, в нашем случае – это Hibernate. Например, такие параметры, как имя пользователя, пароль, адрес БД, отображение SQL-запросов в консоли и тд, рисунок 9. Также при первом запуске приложения flyway, за счет выставленного флага create-schemas – создаст новую схему, соответствующую той, что указана в currentSchema. Для того, чтобы SQL-запросы при выводе отображались в читаемом виде, указывается флаг format_sql. Также в locations описан путь к миграциям, которые будут прогоняться при запуске (только в том случае, если БД еще не была приведена к последней версии).

Рисунок 9 – Конфигурирование.

Для представления модели пользователя создадим таблицу БД, создав соответствующий файл миграции. Его содержимое представлено на рисунке 10.

Рисунок 10 – Таблица users.

На уровне приложения необходимо ввести соответствующий класс, описанный с использованием средств ORM. Рисунок 11. Из основного: указано, что это сущность и указано название таблицы, с которой необходимо соотнести класс-сущность. Также указано поле первичного ключа и правило его генерации. Заданы стандартные значения.

Рисунок 11 – Класс UserE.

Так как большое число ролей и отдельных прав не предусматривается в рамках разрабатываемой платформы, то для цели их писания удобно использовать enum – тип перечисления. Хотя, фактически, это обычный класс, с набором статических констант, представленный немного в другом виде для большего удобства, результат представлен на рисунке 12.

Рисунок 12 – Роли пользователей

Для представления API для работы с сервисом аутентификации – введен интерфейс, рисунок 13.

Рисунок 13 – Сервис аутентификации.

Его реализация представлена на рисунке 14.

Рисунок 14 – Имплементация сервиса аутентификации

В методе register дополнительно происходит проверка наличия пользователя с почтой, что передал пользователь, чтобы исключить дубли (Хотя они исключены уже за счет наличия ограничения UNIQUE на уровне таблицы БД). Как было оглашено ранее, пароль не хранится в чистом виде, а шифруется без возможности дешифрования.

В методе login описана основная логика по авторизации. Первоначально происходит попытка загрузки пользователя из БД на основе переданной почты (логина), после чего, если пользователь найден, с использованием метода matches проверяется корректность введенного пароля. Если данные корректны – происходит аутентификация пользователя и генерация токена, по которому, при последующих запросах, мы сможем идентифицировать пользователя нашей системы. Генерация токена происходит на основе алгоритма HS256 и соли.

Соль (также модификатор входа хэш-функции) — строка входных данных, которая передаётся хеш-функции вместе с входным массивом данных (прообразом) для вычисления хэша (образа).

Используется для:

— усложнения определения прообраза хэш-функции методом перебора по словарю возможных входных значений (прообразов); — скрытия факта использования одинаковых прообразов при использовании для них разной соли.

Различают:

— статическую соль (используемую для всех входных значений); — динамическую соль (генерируемую для каждого входного значения).

Соль и заголовок, в котором мы будем ожидать токен – указан в файле конфигурации. Также описано время жизни токена на случай, если пользователь долго неактивен, рисунок 15.

Рисунок 15 – Конфигурирование безопасности

Основную роль в разграничении прав играет конфиг безопасности, где описаны правила доступа к отдельным эндпоинтам в зависимости от того, аутентифицирован пользователь или нет, и, если да, то какую роль он имеет.

Рисунок 16 – Разграничение доступов.

В результате проделанной работы был разработан API интерфейс для взаимодействия с клиентским сервисом. На рисунках 17-18 представлены страницы аутентификации и регистрации.

Рисунок 17 – Страница регистрации

Рисунок 18 – Страница аутентификации

Дополнительно, на клиентской стороне заданы правила отображения стартовой страницы после входа в систему на основе полученной роли. При первой аутентификации, при вводе корректных данных, в локальное хранилище сохраняется токен, который затем будет подвязываться к каждому запросу к BackEnd по названию Authorization. Пользовательская страница и административная представлены на рисунках 19-20.

Рисунок 19 – Панель управления администратора

Рисунок 20 – Пользовательская панель

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

Для упрощения ориентирования между ними, они были разделены на отдельные пакеты, рисунок 21.

Рисунок 21 – Разграничение по пакетам в зависимости от уровня доступа.

Теперь, когда пользователь аутентифицирован, получить информацию по нему достаточно легко из токена. На основе информации из нее мы можем отобразить его изображение в профиль и личную информацию, которую он указал при регистрации. Эндпоинты, отвечающие за это. Представлены на рисунке 22.

Рисунок 22 – Пользовательский контроллер

Также присутствует ранее неупомянутый метод updateImageProfile, который отвечает за загрузку пользовательского изображения пользователя.

Результат отображения профиля для администратора и пользователя имеет один вид и представлен на рисунке 23.

Рисунок 23 – Профиль пользователя

Результат загрузки нового изображения представлен на рисунках 24-25.

Рисунок 24 – Результат загрузки

Рисунок 25 – Результат после автоматической перезагрузки страницы

Изображения сохраняются локально в директорию, указанную в файле конфигурации. Также там прописано стандартное изображение на случай, если пользователь ничего не задаст. Все это представлено на рисунке 26.

Рисунок 26 – Изображение пользователя

Пришло время добавить категории тестов. Начнем с административного контроллера, который будет содержать эндпоинты создания, удаления, обновления. Путь берется от /api/admin, поэтому доступ к нему будет лишь у администратора портала. Реализация контроллера представлена на рисунке 27.

Рисунок 27 – Административный контроллер управления категориями

Так же, для того чтобы пользователь мог получить информацию о всех доступных категорий, либо же о конкретной, необходимо добавить пользовательский контроллер. Его реализация представлена на рисунке 28.

Рисунок 28 – Пользовательский контроллер получения категорий(и).

Для преставления тела запроса и ответа были введены два класса-DTO. Они представлены на рисунках 29-30.

Рисунок 29 – Класс для представления тела запроса

Рисунок 30 – Класс для представления тела ответа

Для трансформации DTO в класс-сущность и обратно, введены мапперы. За счет использования фреймворка MapStruct, добавление маппера становится достаточно легкой задачей. В большинстве случаев для описания логики маппинга не требуется более число затрат, чем от создания интерфейса и объявления нескольких методов. В результате, на этапе компиляции, с использованием механизма Annotation Processing будут сгенерированы имплементации на основе декларативного описания. Объявление интерфейса и сгенерированная реализация представлены на рисунках 31-32.

Рисунок 31 – Объявление интерфейса

Рисунок 32 – Сгенерированная реализация

В результате проделанной работы у пользователя теперь отображается список доступных категорий тестов, рисунок 33.

Рисунок 33 – Список категорий

На стороне же администратора, помимо обычного просмотра категорий, есть возможность их редактирования, создания и удаления, рисунок 34.

Рисунок 34 – Управление категориями

Рисунок 35 – Обновление категории

Рисунок 36 – Результат обновления

Рисунок 37 – Результат обновления

Также присутствует возможность удаления категории. Для этого достаточно подтвердить свое действие. Рисунок 38.

Рисунок 38 – Удаление категории

Рисунок 39 – Результат удаления категории

Рисунок 40 – Окно создания категории

Рисунок 41 – Результат создания категории

Теперь же нам не хватает тестов. Время их добавить. Начнем с административного контроллера, который будет содержать достаточно много эндпоинтов, так как над тестами можно будет производить немного больше действий. Например, уже знакомые: обновление, удаление, создание, но помимо них будет отдельный эндпоинт их получения, так как некоторые тесты могут быть не общедоступными, а иметь ограниченный доступ. Рисунки 42 – 43.

Рисунок 42 – Административный контроллер по управлению тестами

Рисунок 43 – Административный контроллер по управлению тестами

В результате проделанных действий теперь у администратора присутствует возможность просмотра, редактирования, создания, обновления тестов.

Рисунок 44 – Просмотр списка тестов

Также у тестов должны быть вопросы. Для них также потребуется ввести отдельный контроллер. Результат реализации представлен на рисунке 45, где отображены вопросы по конкретному тесту с возможностью их изменения.

Рисунок 45 – Просмотр списка вопросов к тесту

Со стороны же пользователя, отображаются лишь доступные тесты с некоторой краткой информацией, рисунок 46.

Рисунок 46 – Просмотр списка тестов со стороны пользователя

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

Рисунок 47 – Начало теста

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

Рисунок 48 – Попытка повторно решить тест

Со стороны администратора есть возможность просмотра результатов решения по конкретному тесту, где также присутствует возможность удаления результата решения теста определенного пользователя.

Рисунок 49 – Результаты решения теста

Рисунок 50 – Результат удаления результата прохождения теста

Рисунок 51 – Решение теста

Рисунок 52 – Результат по тесту

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

Рисунок 53 – Просмотр результатов теста

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]