如何使用 Mongoose 在 NodeJS 中进行密码验证
How to make password validation in NodeJS with Mongoose
我有包含用户名、邮箱、密码和密码 2 的注册表。我想验证它们实际匹配的密码。我几乎验证了 Mongoose Scheme 中的所有内容,但我无法在文档中找到任何有用的信息,了解如何在不实际将其保存到数据库的情况下获取 password2。 (我有加密密码的功能,只在保存前运行)
const userSchema = new mongoose.Schema({
username: {
type: String,
unique: true,
required: true,
trim: true,
validate(value) {
if (!validator.isAlphanumeric(value , 'pl-PL')) {
throw new Error('Name cannot contain special characters.')
}
}
},
email: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
password: {
type: String,
required: true,
validate(value) {
console.log(value)
if(value !== this.password2) {
throw new Error("Passwords don't match. Try again.")
}
if(value.length < 8) {
throw new Error("Passwords is too short. At least 8 characters.")
}
}
},
tokens: [{
token: {
type: String,
required: true
}
}]
})
您不需要使 password2
成为 userSchema
的一部分。更好的方法是像这样制作比较密码功能:
UserSchema.methods.comparePassword = function(plaintext, callback) {
return callback(null, Bcrypt.compareSync(plaintext, this.password));
};
你也可以使用 Schema.pre
:
UserSchema.pre("save", function(next) {
if(!this.isModified("password")) {
return next();
}
this.password = Bcrypt.hashSync(this.password, 10);
next();
});
之后,您需要从用户控制器调用比较函数。像这样(取决于你的逻辑):
var user = await UserModel.findOne({ username: request.body.username }).exec();
if(!user) {
return response.status(400).send({ message: "The username does not exist" });
}
user.comparePassword(request.body.password, (error, match) => {
if(!match) {
return response.status(400).send({ message: "The password is invalid" });
}
});
有关详细信息,您可以阅读这篇优秀的 article。
您可以在注册路径中查看password和password2,如果相同则可以继续注册。
注册路由示例如下:
router.post("/register", async (req, res) => {
try {
const { username, email, password, password2 } = req.body;
if (password !== password2) return res.status(400).send("Passwords dont match");
let user = await User.findOne({ email });
//or
//let user = await User.findOne({ username });
if (user) return res.status(400).send("User already registered.");
user = new User({ username, email, password });
user = await user.save();
//todo: at this point you may generate a token, and send to the client in response header or body
res.send(user);
} catch (err) {
console.log(err);
res.status(500).send("Server error");
}
});
我有包含用户名、邮箱、密码和密码 2 的注册表。我想验证它们实际匹配的密码。我几乎验证了 Mongoose Scheme 中的所有内容,但我无法在文档中找到任何有用的信息,了解如何在不实际将其保存到数据库的情况下获取 password2。 (我有加密密码的功能,只在保存前运行)
const userSchema = new mongoose.Schema({
username: {
type: String,
unique: true,
required: true,
trim: true,
validate(value) {
if (!validator.isAlphanumeric(value , 'pl-PL')) {
throw new Error('Name cannot contain special characters.')
}
}
},
email: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
password: {
type: String,
required: true,
validate(value) {
console.log(value)
if(value !== this.password2) {
throw new Error("Passwords don't match. Try again.")
}
if(value.length < 8) {
throw new Error("Passwords is too short. At least 8 characters.")
}
}
},
tokens: [{
token: {
type: String,
required: true
}
}]
})
您不需要使 password2
成为 userSchema
的一部分。更好的方法是像这样制作比较密码功能:
UserSchema.methods.comparePassword = function(plaintext, callback) {
return callback(null, Bcrypt.compareSync(plaintext, this.password));
};
你也可以使用 Schema.pre
:
UserSchema.pre("save", function(next) {
if(!this.isModified("password")) {
return next();
}
this.password = Bcrypt.hashSync(this.password, 10);
next();
});
之后,您需要从用户控制器调用比较函数。像这样(取决于你的逻辑):
var user = await UserModel.findOne({ username: request.body.username }).exec();
if(!user) {
return response.status(400).send({ message: "The username does not exist" });
}
user.comparePassword(request.body.password, (error, match) => {
if(!match) {
return response.status(400).send({ message: "The password is invalid" });
}
});
有关详细信息,您可以阅读这篇优秀的 article。
您可以在注册路径中查看password和password2,如果相同则可以继续注册。
注册路由示例如下:
router.post("/register", async (req, res) => {
try {
const { username, email, password, password2 } = req.body;
if (password !== password2) return res.status(400).send("Passwords dont match");
let user = await User.findOne({ email });
//or
//let user = await User.findOne({ username });
if (user) return res.status(400).send("User already registered.");
user = new User({ username, email, password });
user = await user.save();
//todo: at this point you may generate a token, and send to the client in response header or body
res.send(user);
} catch (err) {
console.log(err);
res.status(500).send("Server error");
}
});