Как безопасно работать с паролями с помощью BcryptJS в JavaScript

Как безопасно работать с паролями с помощью BcryptJS в JavaScript

Даже в небольших проектах защита данных пользователей — не опция, а обязанность. И чем раньше разработчик научится работать с паролями правильно, тем устойчивее будет его приложение — независимо от масштаба и задач. Этот материал подойдёт начинающим и тем, кто хочет обновить свои знания по работе с авторизацией в Node.js.

Если вы разрабатываете и размещаете собственные проекты, обратите внимание на аренду выделенных серверов и VPS — это надёжное решение для тех, кто хочет полный контроль над окружением и безопасность данных.

Почему важно правильно хранить пароли в JavaScript

Защита паролей веб-сайтов — важный навык, которым должен обладать любой разработчик. JavaScript предоставляет возможность обеспечить безопасное хранение и обработку паролей или других конфиденциальных данных с помощью алгоритмов хеширования, предоставляемых модулем BcryptJS.

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

Обсудим, как безопасно обрабатывать пароли в JavaScript с помощью библиотеки BcryptJS — популярной реализации алгоритма bcrypt, полностью написанной на чистом JavaScript. Он идеально подходит для Node.js-приложений, не требует нативной сборки и прост в использовании. Вы узнаете, как устроены хеширование и соление паролей, зачем они нужны и как реализовать регистрацию и вход с использованием Express и MongoDB. Пошаговое руководство поможет настроить надёжную систему хранения паролей, в которой вместо открытого текста в базу попадает безопасный хеш.

Где применяют MongoDB

  • Фронтенд и фулстек-разработчики используют MongoDB в связке с Express и React/Vue в MERN/MEVN-стеке.
  • Стартапы и небольшие команды ценят простоту и гибкость документа-ориентированной модели.
  • Фриланс и агентства часто выбирают MongoDB в проектах, где не нужен сложный SQL-слой и важна скорость разработки.
  • Образование и курсы. MongoDB входит в программы обучения по JavaScript и Node.js.
  • MongoDB часто используют в Open Source и pet-проектах в качестве базы «по умолчанию».

Что ограничивает использование MongoDB

Некоторые компании не используют MongoDB Atlas, потому что он размещён за границей и может попасть под санкции. Вместо этого устанавливают MongoDB на своих серверах или выбирают другие базы данных. В крупных организациях и государственных структурах чаще используют PostgreSQL, MySQL, MS SQL или Oracle — из-за требований по безопасности и совместимости.

Данные, подпадающие под закон о персональных данных, хранятся на российских серверах, и выбор базы зависит от требований к сертификации. MongoDB CE (Community Edition) может не всегда соответствовать таким условиям.

Подготовка

Перейдём к делу. Перед началом работы убедитесь, что у вас:

  • установлена Node.js версии 12.x или выше;
  • установлен Express.js;
  • есть локальная или удалённая MongoDB-база данных;
  • есть базовые знания JavaScript и понимание работы REST API.

Зачем использовать BcryptJS

Библиотека bcrypt — это алгоритм хеширования, предназначенный для безопасного хранения паролей.

Его особенности:

  • Безопасность. Алгоритм специально замедлён для защиты от атак перебора. Это значит, что даже при мощностях современных компьютеров перебрать хеши становится слишком затратным по времени.
  • Автоматическое соление. Для каждого пароля создаётся уникальная соль, которая добавляется к исходной строке перед хешированием. Это делает невозможным использование заранее подготовленных радужных таблиц и затрудняет взлом даже одинаковых паролей.
  • Простота. Модуль BcryptJS легко интегрируется в JavaScript-проекты, работает без зависимостей на нативные библиотеки и подходит для использования как на сервере, так и в браузере.
  • Гибкость. Вы можете настроить сложность хеширования с помощью параметра cost — чем выше значение, тем медленнее будет происходить процесс, но тем надёжнее защита.
  • Поддержка асинхронности. Библиотека BcryptJS работает в неблокирующем режиме, что особенно важно в среде Node.js, позволяя обрабатывать запросы без задержек.

Как работает хеширование

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

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

Пример:

const bcrypt = require("bcryptjs");
const password = 'sammy';
const salt = bcrypt.genSaltSync(10); // генерация соли
const hash = bcrypt.hashSync(password + salt); // хеширование с солью
console.log(hash);

Этот код показывает, как можно надёжно спрятать пароль. Сначала создаётся случайная соль — дополнительная строка, которая прибавляется к паролю перед хешированием. В результате даже одинаковые пароли превращаются в уникальные хеши. Это затрудняет взлом и защищает систему от типичных атак. В реальных проектах лучше использовать встроенный способ bcrypt.hashSync(password, salt) — он сам правильно добавляет соль, что безопаснее, чем вручную объединять строку и соль.

Установка и структура проекта

Создайте структуру проекта и установите необходимые зависимости:

npm init -y
npm install express mongoose bcryptjs nodemon

Создайте следующие файлы:

  • app.js — основной файл сервера,
  • db.js — логика подключения к MongoDB,
  • auth.js — маршруты для регистрации и входа,
  • User.js — модель пользователя для базы данных.

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

Подключение к MongoDB (db.js)

Создадим отдельный модуль, чтобы удобно управлять подключением к базе данных:

const mongoose = require("mongoose");
const mongoURI = "mongodb://127.0.0.1:27017/bcrypt_database";
const connectMongo = async () => {
  try {
    await mongoose.connect(mongoURI);
    console.log("Connected to MongoDB!");
  } catch (error) {
    console.error("Error connecting to MongoDB: ", error.message);
  }
};
module.exports = connectMongo;

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

Модель пользователя (User.js)

Модель определяет структуру документа в MongoDB. Здесь два поля — email и password:

const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true }
});
module.exports = mongoose.model("user", UserSchema);

Этот код создаёт модель пользователя и задаёт правила для хранения данных в MongoDB. Она определяет, что каждый пользователь должен иметь уникальный email и обязательный пароль, обеспечивая базовую валидацию и структуру данных на уровне базы.

Настройка сервера (app.js)

Создаём Express-приложение и подключаем к нему базу данных и маршруты:

const connectToMongo = require("./db");
const express = require("express");
const app = express();
connectToMongo();
app.use(express.json());
app.use("/auth", require("./auth"));
const port = 3300;
app.listen(port, () => {
  console.log(`Listening at http://localhost:${port}`);
});

Этот фрагмент запускает серверное приложение, подключает его к базе данных и настраивает обработку маршрутов. Благодаря этому сервер начинает принимать HTTP-запросы, обрабатывать JSON-данные и перенаправлять их в модуль с логикой регистрации и входа.

Регистрация пользователя (auth.js)

Хешируем пароль перед сохранением его в базе:

const express = require("express");
const router = express.Router();
const User = require("./User");
const bcrypt = require("bcryptjs");
router.post("/signup", async (req, res) => {
  const salt = await bcrypt.genSalt(10);
  const secPass = await bcrypt.hash(req.body.password, salt);
  let user = await User.create({
    email: req.body.email,
    password: secPass
  });
  res.json({ user });
});

Что это даёт:

  1. генерируется соль (genSalt(10));
  2. пароль хешируется с солью (hash(...));
  3. в базу сохраняется только хешированный пароль.

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

Аутентификация пользователя (auth.js)

Сравниваем введённый пароль с хешем, сохранённым в базе:

router.post("/login", async (req, res) => {
  let user = await User.findOne({ email: req.body.email });
  if (!user) {
    return res.status(400).json({ error: "Login with proper credentials!" });
  }
  const passwordCompare = await bcrypt.compare(req.body.password, user.password);
  if (!passwordCompare) {
    return res.status(400).json({ error: "Login with proper credentials!" });
  }
  res.json({ success: "Authenticated!" });
});
module.exports = router;

Здесь:

  • ищем пользователя по email;
  • сравниваем введённый пароль с хешем (compare());
  • отправляем ответ в зависимости от результата.

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

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

Пример запроса на регистрацию:

{
  "email": "test@example.com",
  "password": "yourpassword"
}

Отправляется POST-запрос на:

http://localhost:3300/auth/signup

Этот пример демонстрирует, как работает ручка регистрации: клиент отправляет POST-запрос на указанный адрес с телом, содержащим email и пароль. Это позволяет протестировать работу сервера и убедиться, что пользователь создаётся, а пароль надёжно хешируется перед сохранением в базу.

Заключение

Вы научились настраивать Express-сервер, подключаться к MongoDB, создавать модель пользователя, хешировать пароли с помощью BcryptJS, безопасно аутентифицировать пользователей. Эти шаги закладывают основу безопасной системы авторизации. В дальнейшем можно реализовать JWT-токены, роли, защиту маршрутов, ограничения на вход и другие элементы полноценной системы безопасности.

Если вы планируете размещать своё приложение на удалённом сервере, рассмотрите аренду VPS — это удобный и надёжный способ развернуть проект в Интернете. Мы предлагаем VPS/VDS с быстрыми NVMe-дисками, защитой от DDoS и бесплатной поддержкой — всё, чтобы вы могли сосредоточиться на разработке.

Аренда VPS/VDS от 219 руб/месяц

Преимущества VPS в AdminVPS:

Аренда VPS/VDS виртуального сервера от AdminVPS — это прозрачная и честная услуга с доступной ценой

Читайте в блоге:

Loading spinner
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

VPN на VPS-сервере

Узнайте, как создать собственный VPN на VPS-сервере для защиты ваших конфиденциальных данных!

Что будем искать? Например,VPS-сервер

Мы в социальных сетях