Я следую руководству под названием «Создание безопасной регистрации пользователей и 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
вы отправляете один и тот же пароль 10 раз, поэтому сервер, очевидно, создаст много пользователей с одинаковыми учетными данными.
Может быть, вы хотите знать, почему ваша проверка существующей электронной почты не работает? Если да, отредактируйте заголовок вопроса
Вам необходимо добавить уникальный индекс к имени пользователя, адресу электронной почты или к тому и другому. Удалите всех пользователей из своей коллекции, а затем обновите схему, например email: {type: String, unique: true}
или username: {type: String, unique: true}
. Это обеспечит вставку в коллекцию только уникальных значений.
Добавьте щепотку соли вместо константы 10, чтобы получить разные хеши.
Это распространенная проблема при асинхронных операциях. Это как если бы 10 человек одновременно спросили, есть ли свободный стул. Все 10 из них получают ответ «да», но только один из них может на нем сесть.
Чтобы решить эту проблему, вам следует проверить модель.
const userSchema = new mongoose.Schema({
username: { type: String, unique: true },
email: { type: String, unique: true },
password: String,
});
в чем вопрос