Тема, Мета, Місце розташування
Тема: Адаптивний веб-застосунок ресторану швидкого харчування MacShnaknels
Мета: Мета лабораторної роботи — реалізувати REST API для вебзастосунку MacShnaknels, додати реєстрацію, авторизацію, валідацію даних, захищені маршрути, ролі користувачів, refresh token, logout, оновлення профілю, зміну та відновлення пароля, підтвердження email і підготовку Google OAuth.
Місце розташування:
- GitHub: встав посилання
- Live demo: (встав посилання)
Постановка задачі
У якості основи використано проєкт лабораторної роботи №2 MacShnaknels, у якому вже було реалізовано:
- статичну клієнтську частину сайту ресторану швидкого харчування;
- адаптивний інтерфейс з головною сторінкою, меню, акціями, кошиком і блоком контактів;
- підключення Node.js до MySQL через пакет
mysql2; - використання ORM
Sequelize; - створення моделей
UserтаPost; - реалізацію зв’язку One-to-Many між користувачами та постами;
- базові SQL-запити
SELECT,INSERT,UPDATE,DELETE; - зберігання користувачів і постів у базі даних MySQL.
У лабораторній роботі №3 структура проєкту була збережена, а наявний backend розширено модулем автентифікації та авторизації користувачів. Таким чином, Lab 3 є продовженням Lab 2, а не окремим новим проєктом.
Що повторно використано з Lab 2
У роботі без змін або з мінімальними змінами повторно використано:
- головну сторінку
index.html; - стилі сайту з папки
css; - JavaScript-логіку клієнтської частини з папки
js; - папку
assets/imagesдля графічних ресурсів; - конфігурацію підключення до MySQL;
- модель
User; - модель
Post; - зв’язок One-to-Many між
UserтаPost; - маршрути для роботи з користувачами через
mysql2; - маршрути для роботи з моделями через
Sequelize; - загальну структуру Express-проєкту.
Це дозволило зберегти цілісність вебзастосунку та показати послідовний розвиток проєкту від лабораторної роботи №2 до лабораторної роботи №3.
Нові можливості Lab 3
До проєкту було додано:
- реєстрацію користувача;
- авторизацію користувача;
- підтвердження пароля при реєстрації;
- валідацію введених даних;
- обробку помилок;
- access token;
- refresh token;
- logout;
- захищений маршрут профілю;
- оновлення профілю користувача;
- зміну пароля;
- ролі користувачів
userтаadmin; - middleware для перевірки JWT-токена;
- адміністративні маршрути;
- видалення користувача;
- відновлення пароля;
- підтвердження email;
- обмеження кількості спроб входу;
- логування помилок у файл;
- підготовку Google OAuth-авторизації.
Структура проєкту після доопрацювання
macshnaknels/
│
├── assets/
│ └── images/
│ └── зображення сайту
│
├── css/
│ ├── style.css
│ ├── auth.css
│ └── admin.css
│
├── js/
│ ├── script.js
│ ├── register.js
│ ├── login.js
│ └── admin.js
│
├── backend/
│ ├── src/
│ │ ├── config/
│ │ │ ├── mysql2.js
│ │ │ └── sequelize.js
│ │ │
│ │ ├── models/
│ │ │ ├── User.js
│ │ │ ├── Post.js
│ │ │ └── index.js
│ │ │
│ │ └── server.js
│ │
│ ├── logs/
│ │ ├── access.log
│ │ └── errors.log
│ │
│ ├── .env
│ ├── package.json
│ └── package-lock.json
│
├── index.html
├── register.html
├── login.html
├── admin.html
└── README.md Опис основних файлів
index.html — головна сторінка сайту MacShnaknels. Містить основні блоки інтерфейсу: header, hero-блок, меню, акції, інформацію про заклад, footer та кошик.
register.html — сторінка реєстрації користувача.
login.html — сторінка авторизації користувача.
admin.html — сторінка адміністративної панелі.
css/style.css — основні стилі сайту.
css/auth.css — стилі сторінок реєстрації та входу.
css/admin.css — стилі адміністративної панелі.
js/script.js — основна логіка frontend-частини: меню, кошик, відображення поточного акаунта, logout.
js/register.js — відправлення даних реєстрації на backend.
js/login.js — авторизація користувача та збереження токенів у localStorage.
js/admin.js — логіка адміністративної панелі.
backend/src/server.js — головний файл backend-сервера, у якому реалізовано REST API.
backend/src/config/mysql2.js — підключення до MySQL через пакет mysql2.
backend/src/config/sequelize.js — підключення до MySQL через ORM Sequelize.
backend/src/models/User.js — модель користувача.
backend/src/models/Post.js — модель поста або акції.
backend/src/models/index.js — опис зв’язків між моделями.
Стек технологій
У проєкті використано:
HTML5— створення структури сторінок;CSS3— стилізація інтерфейсу;JavaScript— клієнтська логіка сайту;Node.js— серверне середовище виконання JavaScript;Express.js— створення REST API;MySQL— база даних;XAMPP— запуск локального MySQL-сервера;phpMyAdmin— перегляд і керування базою даних;mysql2— пряме підключення Node.js до MySQL;Sequelize— ORM для роботи з базою даних через моделі;bcryptjs— хешування паролів;jsonwebtoken— створення access token і refresh token;express-validator— валідація даних;express-rate-limit— обмеження кількості спроб входу;morgan— логування HTTP-запитів;nodemailer— підготовка надсилання email;passport— підготовка OAuth-авторизації;passport-google-oauth20— підготовка Google login;dotenv— робота зі змінними середовища;cors— дозвіл запитів між frontend і backend.
REST API маршрути
Успадковані з Lab 2
GET /api/raw/users
POST /api/raw/users
PUT /api/raw/users/:id
DELETE /api/raw/users/:id
POST /api/orm/users
POST /api/orm/posts
GET /api/orm/users-with-posts Ці маршрути використовуються для демонстрації роботи з базою даних через mysql2 та Sequelize.
Додані в Lab 3
POST /api/auth/register
POST /api/auth/login
POST /api/auth/refresh
POST /api/auth/logout
GET /api/auth/me
PUT /api/auth/profile
PUT /api/auth/change-password
DELETE /api/auth/delete-account
POST /api/auth/forgot-password
POST /api/auth/reset-password
GET /api/auth/confirm-email/:token
GET /api/auth/google
GET /api/auth/google/callback Адміністративні маршрути
GET /api/admin/users
PATCH /api/admin/users/:id/role
DELETE /api/admin/users/:id
GET /api/admin/posts
POST /api/admin/posts
PUT /api/admin/posts/:id
DELETE /api/admin/posts/:id Адміністративні маршрути доступні тільки користувачам з роллю admin.
Структура бази даних
У проєкті використовується база даних:
macshnaknels_db Основні таблиці:
users;posts.
Таблиця users
Таблиця users використовується для збереження користувачів системи.
Основні поля:
id — унікальний ідентифікатор користувача;
name — ім’я користувача;
email — електронна пошта;
password — хешований пароль;
role — роль користувача: user або admin;
refreshToken — refresh token користувача;
emailConfirmed — статус підтвердження email;
emailConfirmToken — токен підтвердження email;
resetPasswordToken — токен відновлення пароля;
resetPasswordExpires — час дії токена відновлення пароля;
googleId — ідентифікатор Google-акаунта;
loginAttempts — кількість невдалих спроб входу;
lockUntil — час блокування акаунта після великої кількості невдалих спроб входу. Таблиця posts
Таблиця posts використовується для збереження постів, акцій або новин сайту.
Основні поля:
id — унікальний ідентифікатор поста;
title — назва поста або акції;
content — текстовий опис;
user_id — зовнішній ключ, який посилається на користувача-автора. Зв’язок One-to-Many
Між таблицями users та posts реалізовано зв’язок One-to-Many.
Це означає, що один користувач може створювати багато постів або акцій, але кожен пост належить тільки одному користувачу.
У Sequelize цей зв’язок реалізовано так:
User.hasMany(Post, {
foreignKey: "user_id",
as: "posts",
onDelete: "CASCADE",
});
Post.belongsTo(User, {
foreignKey: "user_id",
as: "author",
}); Для перевірки зв’язку використовується маршрут:
GET /api/orm/users-with-posts Валідація та безпека
У роботі реалізовано:
- перевірку формату email;
- перевірку мінімальної довжини пароля;
- підтвердження пароля під час реєстрації;
- перевірку старого пароля при зміні на новий;
- хешування паролів через
bcryptjs; - використання JWT для захисту маршрутів;
- access token для доступу до захищених ресурсів;
- refresh token для оновлення access token;
- перевірку ролей користувачів;
- middleware для перевірки токена;
- rate limit для обмеження кількості спроб входу;
- логування запитів та помилок у файли;
- обробку помилок через
try/catchта глобальний middleware.
Приклади запитів для тестування
Реєстрація користувача
curl -X POST http://localhost:3000/api/auth/register ^
-H "Content-Type: application/json" ^
-d "{"name":"Herman","email":"herman@example.com","password":"secret123","confirmPassword":"secret123"}" Авторизація користувача
curl -X POST http://localhost:3000/api/auth/login ^
-H "Content-Type: application/json" ^
-d "{"email":"herman@example.com","password":"secret123"}" Отримання профілю користувача
curl http://localhost:3000/api/auth/me ^
-H "Authorization: Bearer ACCESS_TOKEN" Оновлення профілю
curl -X PUT http://localhost:3000/api/auth/profile ^
-H "Content-Type: application/json" ^
-H "Authorization: Bearer ACCESS_TOKEN" ^
-d "{"name":"Updated Herman","email":"updated@example.com"}" Зміна пароля
curl -X PUT http://localhost:3000/api/auth/change-password ^
-H "Content-Type: application/json" ^
-H "Authorization: Bearer ACCESS_TOKEN" ^
-d "{"oldPassword":"secret123","newPassword":"newpass123","confirmNewPassword":"newpass123"}" Refresh token
curl -X POST http://localhost:3000/api/auth/refresh ^
-H "Content-Type: application/json" ^
-d "{"refreshToken":"REFRESH_TOKEN"}" Logout
curl -X POST http://localhost:3000/api/auth/logout ^
-H "Authorization: Bearer ACCESS_TOKEN" Відновлення пароля
curl -X POST http://localhost:3000/api/auth/forgot-password ^
-H "Content-Type: application/json" ^
-d "{"email":"herman@example.com"}" Скидання пароля
curl -X POST http://localhost:3000/api/auth/reset-password ^
-H "Content-Type: application/json" ^
-d "{"token":"RESET_TOKEN","newPassword":"reset123","confirmNewPassword":"reset123"}" Перевірка Google OAuth
curl http://localhost:3000/api/auth/google Якщо GOOGLE_CLIENT_ID та GOOGLE_CLIENT_SECRET не налаштовані у файлі .env, API поверне повідомлення про те, що Google OAuth не налаштовано. Це означає, що інтеграцію підготовлено, але для повної роботи потрібно створити OAuth credentials у Google Cloud Console.
Інструкція запуску проєкту
1. Запустити XAMPP
У XAMPP потрібно запустити:
Apache
MySQL 2. Перейти в папку backend
cd backend 3. Встановити залежності
npm install 4. Запустити backend
npm run dev Після запуску має з’явитися повідомлення:
Підключення до MySQL через Sequelize успішне
Сервер працює на http://localhost:3000 5. Запустити frontend
Frontend-частину потрібно відкрити через Live Server у VS Code.
Основні сторінки:
index.html
register.html
login.html
admin.html Файл .env
Приклад файлу .env:
PORT=3000
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=
DB_NAME=macshnaknels_db
ACCESS_TOKEN_SECRET=macshnaknels_access_secret
REFRESH_TOKEN_SECRET=macshnaknels_refresh_secret
JWT_SECRET=macshnaknels_secret_key
CLIENT_URL=http://127.0.0.1:5500
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_CALLBACK_URL=http://localhost:3000/api/auth/google/callback
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS= Файл .env не потрібно публікувати у GitHub, оскільки він може містити секретні ключі.
Результат виконання
У ході лабораторної роботи було збережено архітектурну основу лабораторної роботи №2 та повторно використано наявну frontend- і backend-структуру вебзастосунку MacShnaknels. Серверну частину було розширено повноцінним REST API для роботи з користувачами.
Було реалізовано реєстрацію, авторизацію, валідацію даних, обробку помилок, захищені маршрути, ролі користувачів, access token, refresh token, logout, оновлення профілю, зміну пароля, видалення користувача, відновлення пароля, підтвердження email, логування помилок та обмеження кількості спроб входу.
Також було підготовлено інтеграцію Google OAuth. У разі додавання GOOGLE_CLIENT_ID та GOOGLE_CLIENT_SECRET у файл .env користувач зможе авторизуватися через Google-акаунт.
Висновки
У лабораторній роботі №3 було виконано розвиток проєкту MacShnaknels без повної перебудови його структури. Клієнтську частину сайту було повторно використано, а серверну логіку доповнено засобами автентифікації та авторизації користувачів.
У результаті вебзастосунок отримав функціональний REST API, який підтримує реєстрацію, вхід, logout, оновлення профілю, зміну пароля, відновлення пароля, підтвердження email, перевірку токена та розмежування прав доступу за ролями user і admin.
Реалізована система є більш наближеною до реального вебсервісу, оскільки забезпечує захист маршрутів, перевірку введених даних, обробку помилок, збереження користувачів у базі даних MySQL та використання JWT-токенів для авторизації.
