Учебный интернет-магазин электроники на Node.js + Express. Реализованы регистрация и авторизация пользователей с хешированием паролей через bcrypt, серверная корзина на сессиях, хранение пользователей в встраиваемой БД NeDB, защита от XSS на клиенте и адаптивный интерфейс на чистом HTML/CSS/JavaScript.
Проект выполнен в рамках расчётно-графической работы по дисциплине «Разработка серверной части интернет-магазина с использованием Node.js и Express».
- Автор: Карчев Дмитрий Владимирович
- Группа: ПИэ-23
- Курс: 3
- ВУЗ: ННГАСУ, Институт информационных технологий
- Год: 2026
| Уровень | Технология |
|---|---|
| Серверная платформа | Node.js |
| Веб-фреймворк | Express |
| Сессии | express-session + session-file-store |
| Хеширование паролей | bcrypt |
| База данных пользователей | NeDB (nedb-promises) |
| Каталог товаров | JSON-файл |
| Переменные окружения | dotenv |
| Автоперезапуск (dev) | nodemon |
| Клиент | HTML5, CSS3, JavaScript ES6+ (Fetch API) |
ElectroStore/
├── app.js # Точка входа, настройка Express и сессий
├── package.json
├── nodemon.json # Настройка автоперезапуска в dev-режиме
├── .env # Локальные переменные окружения (не в git)
├── .env.example # Шаблон для .env
├── .gitignore
├── README.md
├── data/ # Хранилище данных
│ ├── products.json # Каталог товаров
│ ├── users.db # База пользователей (NeDB)
│ └── sessions/ # Файлы сессий
├── lib/ # Внутренние модули
│ ├── storage.js # Работа с JSON-файлами
│ └── userStore.js # Работа с базой пользователей
├── routes/ # Маршруты API
│ ├── auth.js # /api/auth/*
│ ├── cart.js # /api/cart/*
│ └── products.js # /api/products/*
└── public/ # Клиентская часть
├── index.html
├── products.html
├── cart.html
├── profile.html
├── css/
│ └── style.css
└── js/
├── global.js # Общие функции: escapeHtml, requestJSON,
│ # updateCartCount, addToCart, checkAuth
├── products.js # Логика каталога
├── cart.js # Логика корзины
└── profile.js # Регистрация / вход / выход
git clone https://github.com/<твой-логин>/ElectroStore.git
cd ElectroStorenpm installСкопируй шаблон:
cp .env.example .envИли в PowerShell:
Copy-Item .env.example .envЗатем сгенерируй собственный SESSION_SECRET:
node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"Вставь полученное значение в .env:
PORT=3000
SESSION_SECRET=<длинная_случайная_строка>
NODE_ENV=development
Для разработки (с автоперезапуском при изменении кода):
npm run devДля обычного запуска:
npm startПосле запуска сервер будет доступен по адресу:
http://localhost:3000
| Метод | Путь | Описание |
|---|---|---|
GET |
/api/products |
Получить весь каталог |
GET |
/api/products/:id |
Получить товар по ID |
| Метод | Путь | Тело | Описание |
|---|---|---|---|
GET |
/api/cart |
— | Содержимое корзины, сумма, количество |
POST |
/api/cart/add |
{ productId, quantity } |
Добавить товар |
POST |
/api/cart/remove |
{ productId } |
Удалить товар |
| Метод | Путь | Тело | Описание |
|---|---|---|---|
POST |
/api/auth/register |
{ name, email, password } |
Регистрация (пароль ≥ 6 символов) |
POST |
/api/auth/login |
{ email, password } |
Вход |
POST |
/api/auth/logout |
— | Выход и очистка cookie |
GET |
/api/auth/me |
— | Текущий пользователь или null |
- Хеширование паролей:
bcryptс 10 раундами соли — в БД хранится только хеш, оригинальный пароль восстановить невозможно. - Сессии: идентификатор сессии передаётся в
httpOnlycookie с флагомsameSite: lax, что защищает от чтения через JavaScript и снижает риск CSRF-атак. - Срок жизни сессии: 24 часа (
maxAge: 86400000). - Уникальность email: на уровне БД (уникальный индекс NeDB) — повторная регистрация невозможна.
- Защита от XSS: на клиенте все данные, поступающие с сервера, экранируются через функцию
escapeHtml()вpublic/js/global.jsперед вставкой черезinnerHTML. - Секрет сессии: хранится в
.env(исключён из репозитория через.gitignore). - Валидация ввода: на сервере проверяются обязательные поля, длина пароля, существование товара.
Клиентская часть построена как набор статических HTML-страниц с динамической загрузкой данных через Fetch API. Перед страничными скриптами на всех страницах подключается общий скрипт global.js, содержащий переиспользуемые функции:
escapeHtml(value)— экранирование HTML-сущностей (защита от XSS)requestJSON(url, options)— обёртка надfetchс обработкой ошибокupdateCartCount()— обновление счётчика корзины в шапкеaddToCart(productId, quantity)— добавление товара в корзинуcheckAuth()— проверка текущей сессии пользователя
Такой подход позволяет избежать дублирования кода между страницами и централизованно обрабатывать общие задачи (XSS-защита, обновление UI, обращения к API).
Регистрация (с сохранением cookie):
curl -X POST http://localhost:3000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name":"Иван","email":"ivan@test.ru","password":"123456"}' \
-c cookies.txtДобавление товара в корзину (используя сохранённую cookie):
curl -X POST http://localhost:3000/api/cart/add \
-H "Content-Type: application/json" \
-d '{"productId":1,"quantity":2}' \
-b cookies.txt -c cookies.txtПросмотр корзины:
curl http://localhost:3000/api/cart -b cookies.txtПолучение текущего пользователя:
curl http://localhost:3000/api/auth/me -b cookies.txtФайл nodemon.json настроен так, чтобы автоперезапуск не реагировал на изменения в папках data/ и public/. Это предотвращает циклический перезапуск сервера при записи NeDB в users.db и сохранении сессий, а также не перезапускает сервер при редактировании клиентских файлов (для них достаточно обновить страницу в браузере).
- Добавить очистку корзины (
POST /api/cart/clear) и оформление заказа. - Сохранять корзину в БД с привязкой к пользователю (переживёт logout).
- Реализовать страницу с детальным описанием товара.
- Добавить административную панель для управления каталогом.
- Перенести каталог из JSON-файла в NeDB.
- Подключить HTTPS и установить
cookie.secure = trueдля production. - Добавить защиту от brute-force (
express-rate-limit) на/api/auth/login. - Покрыть API автотестами на Jest.
Учебный проект. Все права на использование кода принадлежат автору.