Я создаю Node, основанный на Express API для аутентификации пользователей. Я использую монго для хранения данных. Используя почтальон, я отправил запрос /post, передав следующий объект
{
"username": "abc",
"password": "abc123",
"email": "[email protected]"
}
под треб.тел.
Вот как моя функция /post выглядит в коде:
//create one user
router.post('/createUser', async (req, res) => {
if (!req.body.email || !req.body.password || !req.body.username) {
return res.status(400).send({
message: "No username/password/email specified"
});
}
const newUser = new User({
email: req.body.email,
username: req.body.username,
password: req.body.password
});
await User.create(newUser, (err, data) => {
//res.send(data);
if (err) {
console.info(err);
res.status(500).send('Error creating user');
}
});
});
Метод User.create() вызывает метод .save() скрыто. У меня есть предварительное условие сохранения для шифрования паролей. При запуске поста я получаю сообщение об ошибке UnhandledPromiseRejectionWarning: Error: data and salt arguments required
Я сделал несколько журналов консоли и заметил, что это происходит потому, что user.password входит как неопределенный. Так что похоже, что мой запрос не проходит должным образом от почтальона.
Редактировать: Вот схема:
const userSchema = new mongoose.Schema({
id: {
type: Number
},
email: {
type: String,
unique: true,
required: true,
},
username: {
type: String,
unique: true,
required: true
},
password: {
type: String,
required: true
},
});
userSchema.pre('save', (next) => {
const user = this;
console.info(user.password);
bcrypt.hash(user.password, 10, (err, hash) => {
if (err) {
next(err);
} else {
user.password = hash;
next();
}
});
});
Может кто-нибудь, пожалуйста, помогите мне понять, что не так?
Не могли бы вы поделиться своим create() методом и schema определением?
Можете ли вы показать свой предварительный крючок?
Я добавил определение схемы к вопросу
Можете ли вы переписать свой вопрос, потому что проблема не выглядит так, как будто она имеет какое-либо отношение к самой операции POST, а к вашему способу вызова кода в вашем .pre действии.
Причина, по которой я думаю, что почтовый запрос не проходит, потому что я не получаю никаких данных для req.body.username, req.body.password и т. д.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Пароль от почтальона получает ваш код NodeJS.
В вашем коде:
const newUser = new User({
email: req.body.email,
username: req.body.username,
password: req.body.password
});
когда вы это сделаете, ваш ожидаемый результат от newUser изменится.
поэтому, когда ваш код достигает здесь...
const user = this;
console.info(user.password);
Вместо регистрации user.password попробуйте зарегистрировать самого пользователя, например...
console.info(user)
и посмотреть, если "(const user=this)" дает то, что вы ожидали.
Я попробовал это, и он возвращается как undefined. Я понимаю, что могут отсутствовать параметры req.body, как я уже упоминал в вопросе. Но я не могу понять, почему это происходит.
signUp: (req, res, next) => {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(req.body.password, salt, (err, hashedPass) => {
let insertquery = {
'_id': new mongoose.Types.ObjectId(),
'username': req.body.username,
'email': req.body.password,
'salt': salt,
'password': hashedPass
};
user.create(insertquery, function (err, item) {
});
});
});
}
Вы не можете использовать функцию стрелки в хуках .pre, потому что функция стрелки не связывает "это". Предполагается, что «это» относится к каждому отдельному пользователю, которого нужно сохранить. однако, если вы используете this внутри функции стрелки, она будет указывать на глобальный объект. запустите этот код console.info(это), который вы увидите. используйте стрелочные функции для автономных функций. в вашем случае вы создаете метод, который является частью объекта, поэтому вам следует избегать использования функции стрелки
Я не использую .pre, потому что некоторые запросы мангуста обходят промежуточное ПО мангуста, поэтому вам нужно проделать дополнительную работу. поэтому вместо этого я хэширую пароль внутри маршрутизатора, поэтому все, что связано с пользователем, будет в одном месте. единственный источник правды
const bcrypt = require("bcrypt");
router.post('/createUser', async (req, res) => {
if (!req.body.email || !req.body.password || !req.body.username) {
return res.status(400).send({
message: "No username/password/email specified"
});
}
const newUser = new User({
email: req.body.email,
username: req.body.username,
password: req.body.password
});
//we created newUser and now we have to hash the password
const salt = await bcrypt.genSalt(10);
newUser.password = await bcrypt.hash(newUser.password, salt);
await newUser.save();
res.status(201).send(newUser)
//201 code success for something is created
});
вот список кодов состояния http:
это, безусловно, то, что я искал. Теперь он работает так, как ожидалось. Тем не менее, мне любопытно, почему предварительный хук не будет работать, когда мы, по сути, делаем один и тот же процесс.
можешь поделиться схемой?