这是我的身份验证过程:
会话> Controller.js
const jwt = require("jsonwebtoken");
const repository = require("./repository");
const config = require("../../config");
const logger = require("../../utilities/logger");
exports.login = async (req, res) => {
if (!req.body.password || !req.body.username) {
res.preconditionFailed("Credentials required");
return;
}
try {
const user = await repository.findUser(req.body);
if (!user || !user.comparePasswords(req.body.password)) {
res.json({ success: false, message: "Authentication failed." });
return;
}
const token = jwt.sign(user.toObject(), config.secret, { expiresIn: 1440 });
logger.info("User loged in with success. Login token", token);
res.json({
success: true,
token,
});
} catch (err) {
res.send(err);
}
};
用户> Model.js
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const SALT_WORK_FACTOR = 10;
const Schema = mongoose.Schema;
const userSchema = new Schema({
id: { type: String, required: true },
username: { type: String, required: true },
password: { type: String, required: true },
}, {
timestamps: true,
});
userSchema.pre('save', function(next) {
var user = this;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next();
// generate a salt
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if (err) return next(err);
// hash the password using our new salt
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) return next(err);
// override the cleartext password with the hashed one
user.password = hash;
next();
});
});
});
userSchema.methods.comparePasswords = function(candidatePassword) {
return bcrypt.compareSync(candidatePassword, this.password);
};
module.exports = mongoose.model("User", userSchema);
在用户模型中,我正在使用bcrypt方法compareSync
。建议使用异步方法compare
(https://www.npmjs.com/package/bcrypt)。
有人可以解释为什么吗?什么样的实现才是好的?这样工作得很好,但是我想确保我正在使用最佳实践。
答案 0 :(得分:1)
compareSync
是占用大量CPU的任务。由于Node.js Event Loop是单线程的,因此除非比较完成,否则您将阻止整个应用程序。
使用node.js的主要规则是始终避免同步代码执行。
原因是框架的event-driven
性质。
可以找到很好的详细说明here