#javascript #mongodb #express #mongoose
#javascript #mongodb #выразить #mongoose
Вопрос:
У меня есть простой сервер ExpressJS / Node, который содержит базу данных MongoDB, для взаимодействия с которой я использую mongoose. Я могу добавлять объекты в базу данных на основе UserSchema:
const userSchema = mongoose.Schema({
email : {
type: String,
required: true,
trim: true,
unique: 1
},
password : {
type: String,
required: true,
minlength: 5
},
name : {
type: String,
required: true,
maxlength: 30
},
lastname : {
type: String,
required: true,
maxlength: 30
},
cart : {
type : Array,
default: []
},
history : {
type: Array,
default: []
},
role : {
type: Number,
default : 0
},
token : {
type: String
}
});
С сервера express я могу зарегистрироваться и добавить нового пользователя в базу данных, и я знаю, что это работает
Server.js
//========================================
// Register User
//========================================
app.post('/api/users/register', (req, res) => {
//create new User
const user = new User(req.body);
//save user
user.save((err, doc) => {
if(err)
return res.json({success: false, err});
res.status(200).json({
success : true,
userdata: doc
});
});
})
В User.js
//========================================
// SAVE in DB
//========================================
const User = mongoose.model('User', userSchema);
Теперь, когда я хочу войти в систему, операция, при которой мне нужно проверить соответствие электронной почты и пароля, я сталкиваюсь с проблемой, когда все в порядке, и я хочу добавить JWT к объекту, все хорошо, пока он не перейдет к методу сохранения, ничего не происходит, и он больше не отвечает. Похоже, что это происходит в бесконечном цикле. Я получаю сообщение об ошибке, когда что-то не так, но в положительном случае оно исчезает и не отправляет ответа ни в mongo, ни в node, ни в debug что-либо еще.
Server.js
app.post('/api/users/login', (req, res) => {
//find the email for the user
User.findOne({'email' : req.body.email} , (err, user) =>{
if(!user)
return res.json({loginSuccess : false, message : 'Authentication failed, email not found'});
//check the password
user.comparePassword(req.body.password, (error, isMatch) => {
if(!isMatch)
return res.json({loginSuccess : false, message : 'Wrong password'});
//generate token
user.generateToken((err, user) => {
if(err)
return res.status(400).send(err);
//store token as a cookie
res.cookie('w_auth', user.token).status(200).json({
loginSuccess : true
})
})
})
})
})
User.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const SALT_I = 10;
require('dotenv').config();
//========================================
// User Login
//========================================
userSchema.methods.comparePassword = function (candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(error, isMatch){
if(error)
return cb(error);
cb(null, isMatch);
})
}
userSchema.methods.generateToken = function (cb) {
var user = this;
var token = jwt.sign(user._id.toHexString(),process.env.SECRET)
user.token = token;
user.markModified('anything');
user.save(function(err,user){
if(err) return cb(err);
cb(null,user);
})
}
Я больше не получаю отзывов в консоли узла, debug, Mongo или даже Postmen (я могу подождать здесь несколько минут) после user.save (…) . Я знаю, что он получает хорошего пользователя и все такое, но я действительно не знаю, что делать дальше. Также в Mongo я не вижу поля для токена, я изначально добавляю объект без токена, может ли это повлиять на все? Существует ли другая процедура для обновления существующего объекта в коллекции?
На случай, если для просмотра кода необходим GitHub: Ссылка
Ответ №1:
Действительно, это действительно странно, не удалось отладить, что не так с этим методом ‘save’. Однако в качестве обходного пути этот, похоже, работает нормально:
userSchema.methods.generateToken = function (cb) {
var user = this;
var token = jwt.sign(user._id.toHexString(), "mystupidsecret");
console.log("in generateToken");
console.log(user);
user.token = token;
console.log(user.token);
var email = user.email;
//save token
User.updateOne({ _id: user._id }, { $set: { token: token } }, function(err, user){
if(err) {
console.log(err);
return cb(err);
}
cb(null, user);
// this one is for debug only!
User.findOne({'email' : email} , (err, user) =>{
console.log("After update: ", user)
});
});
console.log('done');
}
Это приводит к следующему:
After update: { cart: [],
history: [],
role: 0,
_id: 5f3e48f09c7edc3f1c24a860,
email: 'abc233@wp.pl',
password:
'$2b$10$iDeeehLOzbQi3dawqW8Lg.HPOvcRBDIS/YD9D1EmqBOH9Be31WpX2',
name: 'ABCDEFGH',
lastname: 'Doeasdasdas',
__v: 0,
token:
'eyJhbGciOiJIUzI1NiJ9.NWYzZTQ4ZjA5YzdlZGMzZjFjMjRhODYw.aH9tCMbIK9t3CReiQg3Azln9Ca8xS7W0xL3qCMOKniY' }
Комментарии:
1. Это устраняет проблему, единственное, что нужно сказать, в моем случае я не могу вернуть пользователя из обновления, потому что я не могу использовать его для хранения cookie, немного странно, но все хорошо. Спасибо!