Потратив 2 ночи (и немного терпения), я наконец завершил реализацию всех эндпоинтов! В какой-то момент это очень наскучило, но я все равно продолжал писать их.
Архитектура папок теперь выглядит вот так:
Всего реализовано 38 эндпоинтов , и это еще не конец — их количество будет расти! Последний из них ощущался как будто я пробежал марафон.
Разработка дизайна 🎨
Но как делать веб без дизайна? Верно, никак! 🤔
Зайдя в Figma и подсмотрев интерфейс GitHub'а , я накидал ориентировочный дизайн страниц регистрации и входа.
Верстка 🖥️
Верстка — это немного рутинное занятие, но результат того стоит!
Могу сказать, что получилось почти идентично дизайну.
Frontend с Vue.js
Почему Vue.js ? Просто такие условия 🙃. Если бы выбор был за мной, я бы взял React .
Добавлю в решение новый проект Веб-приложение ASP.NET Core (MVC) . Стандартный шаблон создаст такие папки:
wwwroot
Это корневая папка для статических файлов, которые будут доступны напрямую через браузер.
Controllers
Папка содержит классы контроллеров, которые управляют маршрутизацией.
Models
Папка содержит модели данных, которые представляют сущности приложения.
Views
Папка содержит представления — файлы, которые отвечают за отображение HTML-страниц пользователю.
В папку wwwroot/lib добавлю клиентскую библиотеку Vue.js .
Создам новый контроллер для страниц аутентификации.
В папке Views есть еще 2 папки:
В папку Shared добавлю новый шаблон страницы Razor с названием _LoginLayout для страниц аутентификации.
Создам папку Auth, добавив туда пустую страницу Razor с названием _ViewStart. Этот файл указывает какой шаблон будут использовать страницы.
@{
Layout = "_LoginLayout";
}
Теперь закину в wwwroot/css свой файл со стилем, который наверстал.
Логика фронтенда 🧠
Начну со страницы входа, добавив HTML-разметку, которую наверстал.
Снизу файла напишу блок скриптов:
@Section scripts {
<script src="~/lib/vue/vue.global.js"></script>
<script>
...тут будут все скрипты...
</script>
}
Пример запроса на бэкенд:
На скрине показан метод ассинхронный метод login(), в нем реализована отправка запроса на эндпоинт /auth/login, если запрос проходит успешно, я записываю Access-токен в локальное хранилище и перенаправляю пользователя на страницу по адресу /home. В противном случае я показываю ошибку пользователю.
В ответе сервера я получаю Access и Refresh токены.
Пример записи куки на сервере:
Здесь я записал новую куку с под названием refreshToken, и значением, равным Refresh-токену.
Вообще для чего мне Refresh-токен, если есть Access? Все очень просто, у Access-токена срок жизни 15 минут, поэтому через 15 минут его необходимо будет сгенерировать заново. Для этого как раз и понадобится Refresh-токен.
По истечению Access-токена я буду посылать на сервер запрос со своими куками. Сервер прочитает Refresh-токен из них и, если он валидный, вернет новый Access-токен.
Как это реализовано со стороны сервера:
При загрузке страницы сразу же срабатывает метод checkRefreshToken, далее отправляется запрос на /auth/refresh. Если сервер возвращает положительный ответ, записываю новый Access в локальное хранилище и продолжаю пользоваться сервисом.
Тестирование 🧪
Запущу бэкенд и фронтенд.
После запуска я сразу попадаю на страницу входа.
Войду в аккаунт, который я создвал еще на начальных этапах.
Если сейчас обратиться по адресу /home, меня перекинет назад на страницу авторизации.
Попробую сначала ввести неправильный пароль.
Теперь введу правильный пароль. Все сработало! Я попал на домашнюю страницу.
Зайдя в консоль разработчика, можно посмотреть локальное хранилище и найти там Access-токен.
Теперь я могу пользоваться сервисом, отправляя запросы на эндпоинты, передавая данный токен в заголовке.