В сегодняшнюю цифровую эпоху создание безопасной системы аутентификации необходимо для любого веб-приложения. Один из самых популярных способов создания безопасной системы аутентификации — использование NodeJS и MongoDB. В этом руководстве мы рассмотрим процесс создания безопасной системы аутентификации с помощью NodeJS и MongoDB.

Во-первых, нам нужно создать новый проект NodeJS и установить необходимые зависимости. Мы будем использовать ExpressJS в качестве веб-фреймворка и Mongoose в качестве драйвера MongoDB. После того, как мы настроили наш проект и установили зависимости, мы можем приступить к созданию нашей системы аутентификации.

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

Далее мы создадим наши маршруты аутентификации в ExpressJS. Мы создадим маршруты для регистрации нового пользователя, входа и выхода. В маршруте регистрации мы проверим ввод пользователя и создадим нового пользователя в MongoDB. В маршруте входа мы проверим учетные данные пользователя и сгенерируем веб-токен JSON (JWT) для аутентификации пользователя.

Мы также создадим промежуточное ПО для проверки JWT в последующих запросах к защищенным маршрутам. Это промежуточное ПО проверит подпись JWT и дату истечения срока действия, гарантируя, что пользователь все еще аутентифицирован.

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

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

Конечно! Вот полный пример создания безопасной системы аутентификации с помощью NodeJS и MongoDB:

  1. Настройте проект и установите зависимости:
mkdir node-auth
cd node-auth
npm init -y
npm i express mongoose bcrypt jsonwebtoken dotenv

2. Создайте файл .env для хранения переменных среды:

touch .env

Добавьте в файл .env следующие переменные:

MONGODB_URI=mongodb://localhost:27017/node-auth
SECRET_KEY=mysecretkey

3. Создайте файл db.js для подключения к MongoDB:

const mongoose = require('mongoose');
require('dotenv').config();

const connectDB = async () => {
  try {
    await mongoose.connect(process.env.MONGODB_URI, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useCreateIndex: true,
      useFindAndModify: false
    });
    console.log('Connected to MongoDB');
  } catch (error) {
    console.log('Error connecting to MongoDB:', error);
  }
};

module.exports = connectDB;

4. Создайте файл models/User.js для определения схемы пользователя:

const mongoose = require('mongoose');
const bcrypt = require('bcrypt');

const userSchema = new mongoose.Schema(
  {
    username: {
      type: String,
      required: true,
      unique: true
    },
    email: {
      type: String,
      required: true,
      unique: true
    },
    password: {
      type: String,
      required: true
    },
    role: {
      type: String,
      enum: ['user', 'admin'],
      default: 'user'
    }
  },
  { timestamps: true }
);

// Hash the password before saving it to the database
userSchema.pre('save', async function (next) {
  const user = this;
  if (!user.isModified('password')) return next();

  try {
    const salt = await bcrypt.genSalt();
    user.password = await bcrypt.hash(user.password, salt);
    next();
  } catch (error) {
    return next(error);
  }
});

// Compare the given password with the hashed password in the database
userSchema.methods.comparePassword = async function (password) {
  return bcrypt.compare(password, this.password);
};

const User = mongoose.model('User', userSchema);

module.exports = User;

5. Создайте файл controllers/auth.js для обработки запросов аутентификации:

const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const User = require('../models/User');

// Register a new user
const register = async (req, res, next) => {
  const { username, email, password } = req.body;

  try {
    const hashedPassword = await bcrypt.hash(password, 10);
    const user = new User({ username, email, password: hashedPassword });
    await user.save();
    res.json({ message: 'Registration successful' });
  } catch (error) {
    next(error);
  }
};

// Login with an existing user
const login = async (req, res, next) => {
  const { username, password } = req.body;

  try {
    const user = await User.findOne({ username });
    if (!user) {
      return res.status(404).json({ message: 'User not found' });
    }

    const passwordMatch = await user.comparePassword(password);
    if (!passwordMatch) {
      return res.status(401).json({ message: 'Incorrect password' });
    }

    const token = jwt.sign({ userId: user._id }, process.env.SECRET_KEY, {
      expiresIn: '1 hour'
    });
    res.json({ token });
  } catch (error) {
    next(error);
  }
};

module.exports = { register, login };

6. Создайте файл `middlewares/auth.js` для обработки промежуточного ПО аутентификации:

const jwt = require('jsonwebtoken');
const User = require('../models/User');

const authenticate = async (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];

  if (!token) {
    return res.status(401).json({ message: 'Authentication required' });
  }

  try {
    const decodedToken = jwt.verify(token, process.env.SECRET_KEY);
    const user = await User.findById(decodedToken.userId);
    if (!user) {
      return res.status(404).json({ message: 'User not found' });
    }

    req.user = user;
    next();
  } catch (error) {
    res.status(401).json({ message: 'Invalid token' });
  }
};

module.exports = { authenticate };

7. Создайте файл routes/auth.js для определения маршрутов аутентификации:

const express = require('express');
const { register, login } = require('../controllers/auth');

const router = express.Router();

router.post('/register', register);
router.post('/login', login);

module.exports = router;

8. Создайте файл routes/user.js для определения маршрутов пользователей:

const express = require('express');
const { authenticate } = require('../middlewares/auth');

const router = express.Router();

router.get('/profile', authenticate, (req, res) => {
  res.json({ message: `Welcome ${req.user.username}` });
});

module.exports = router;

9. Создайте файл index.js для запуска сервера:

const express = require('express');
const connectDB = require('./db');
const authRoutes = require('./routes/auth');
const userRoutes = require('./routes/user');

const app = express();
const PORT = process.env.PORT || 3000;

// Connect to MongoDB
connectDB();

// Parse JSON request body
app.use(express.json());

// Define authentication routes
app.use('/auth', authRoutes);

// Define user routes
app.use('/user', userRoutes);

// Start the server
app.listen(PORT, () => {
  console.log(`Server started on port ${PORT}`);
});

С помощью этой настройки вы можете зарегистрировать нового пользователя, отправив POST запрос к /auth/register со следующим телом JSON:

{
  "username": "john.doe",
  "email": "[email protected]",
  "password": "password123"
}

Затем вы можете войти в систему с тем же пользователем, отправив POST запрос к /auth/login со следующим телом JSON:

{
  "username": "john.doe",
  "password": "password123"
}

Сервер ответит объектом JSON, содержащим токен:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MGMwZDQ2NTgzOWM1MTQ2ODZjYzZiYTAiLCJpYXQiOjE2MTkxMzcyNjAsImV4cCI6MTYxOTE0MDg2MH0.wJGkkTz27e_vyaxf1M85rMUPtNvXo25ntGtJgdy-aNk"
}

Затем вы можете получить доступ к профилю пользователя, отправив запрос GET к /user/profile со следующим заголовком Authorization:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MGMwZDQ2NTgzOWM1MTQ2ODZjYzZiYTAiLCJpYXQiOjE2MTkxMzcyNjAsImV4cCI6MTYxOTE0MDg2MH0.wJGkkTz27e_vyaxf1M85rMUPtNvXo25ntGtJgdy-aNk

Сервер ответит объектом JSON, содержащим приветственное сообщение:

{
  "message": "Welcome john.doe"
}

В этом примере показано, как вы можете создать безопасную систему аутентификации с помощью Node.js и MongoDB, используя веб-токены JSON. Следуя шагам, описанным в этом руководстве, вы сможете создать надежную систему аутентификации для своих собственных приложений Node.js.