Как обрабатывать несколько запросов (Express.js) с помощью операции вставки mongodb

Контекст

Я следую руководству под названием «Создание безопасной регистрации пользователей и API входа в систему с помощью Express.js, MongoDB и JWT»

Он использует express bcryptjs jsonwebtoken mongoose для создания простого веб-сервера с функцией регистрации/входа.

Проблема

Проблема возникает, когда я отправляю множество запросов на /api/register. Сервер создает множество пользователей с одинаковыми учетными данными.

Код для воспроизведения

Сервер

// Importing required modules
const express = require('express');
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

// Creating an Express application instance
const app = express();
const PORT = 3000;

// Connect to MongoDB database
mongoose.connect('mongodb://localhost:27017/mydatabase')
    .then(() => {
        console.info('Connected to MongoDB');
    })
    .catch((error) => {
        console.error('Error connecting to MongoDB:', error);
    });

// Define a schema for the User collection
const userSchema = new mongoose.Schema({
    username: String,
    email: String,
    password: String
});

// Create a User model based on the schema
const User = mongoose.model('User', userSchema);

// Middleware to parse JSON bodies
app.use(express.json());

// Route to register a new user
app.post('/api/register', async (req, res) => {
    try {
        // Check if the email already exists
        const existingUser = await User.findOne({email: req.body.email});
        if (existingUser) {
            return res.status(400).json({error: 'Email already exists'});
        }

        // Hash the password
        const hashedPassword = await bcrypt.hash(req.body.password, 10);

        // Create a new user
        const newUser = new User({
            username: req.body.username,
            email: req.body.email,
            password: hashedPassword
        });

        await newUser.save();
        console.info(newUser)
        res.status(201).json({message: 'User registered successfully'});
    } catch (error) {
        console.info('Internal server error')
        res.status(500).json({error: 'Internal server error'});
    }
});

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

Клиент

(() => {
    const send = () => fetch('http://127.0.0.1:3000/api/register', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            "username": "testuser", "email": "[email protected]", "password": "testpassword"
        })
    }).then()

    for (let i = 0; i < 10; i++) send()
})()

Выход

{
  username: 'testuser',
  email: '[email protected]',
  password: '$2a$10$5Jo01CQ797EuMrujH49Of.OmFY4n6yIX.4VgU8FOEhXRmr.CxHnRy',
  _id: new ObjectId('668cf24a08fa6ed9fbf442d5'),
  __v: 0
}
...9 more users created

в чем вопрос

cmgchess 09.07.2024 10:26

вы отправляете один и тот же пароль 10 раз, поэтому сервер, очевидно, создаст много пользователей с одинаковыми учетными данными.

sidgate 09.07.2024 10:54

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

pierpy 09.07.2024 11:22

Вам необходимо добавить уникальный индекс к имени пользователя, адресу электронной почты или к тому и другому. Удалите всех пользователей из своей коллекции, а затем обновите схему, например email: {type: String, unique: true} или username: {type: String, unique: true}. Это обеспечит вставку в коллекцию только уникальных значений.

jQueeny 09.07.2024 13:24

Добавьте щепотку соли вместо константы 10, чтобы получить разные хеши.

Alex Blex 10.07.2024 01:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это распространенная проблема при асинхронных операциях. Это как если бы 10 человек одновременно спросили, есть ли свободный стул. Все 10 из них получают ответ «да», но только один из них может на нем сесть.

Чтобы решить эту проблему, вам следует проверить модель.

const userSchema = new mongoose.Schema({
  username: { type: String, unique: true },
  email: { type: String, unique: true },
  password: String,
});

Другие вопросы по теме