问题描述
我想用 Node.js 和 MongoDB 来做我的登录 API,当我比较从输入到数据库中的传递时,我总是得到错误我阅读了 StackOverFlow 上的其他帖子,但没有帮助我。>
我想我也发现了这个问题:当我在我的密码输入上使用哈希来手动检查它时,每次请求都来自 db 是 onatherone。
所以也许这就是问题所在,但我不知道如何解决。我读了很多关于这个但仍然无法解决这里是我的代码:
const match = await bcrypt.compare(password,user.password,(res) => {console.log(res)}) //false
我的登录api
router.post('/login',body('email').isEmail(),body('password').exists(),async (req,res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() })
}
const { email,password } = req.body
const user = await User.findOne({ email })
if (!user) {
return res.status(401).json({ "err": "invalid credentials" })
}
// const match = await bcrypt.compare(password,user.password).then(function (res) { console.log(res) })
const match = await bcrypt.compare(password,user.password);
console.log(match)
})
这里是注册api
router.post("/register",body("email").isEmail(),body("password").isLength({ min: 5 }),body("username").isLength({ min: 1 }),res) => {
const { email,username,password } = req.body
const errors = validationResult(req);
const saltRounds = 10;
try {
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() })
}
//check if the user exist
const duplicated = await User.findOne({ email })
if (duplicated) { return res.status(401).json({ "err": "Email is taken" }) }
const user = new User({ username,email,password })
//crypt pass
user.password = bcrypt.hashSync(process.env.secret,saltRounds);
//generate token with jwt
const payload = {
id: user.id
}
jwt.sign({
payload,},process.env.jwtSecret,{ expiresIn: '999h' },(err,token) => { console.log(token) });
//save the user
await user.save()
res.status(200).send("User Stored")
} catch (error) {
res.status(500).send(error.body)
}
})
解决方法
为此尝试使用 Promise
const match = await new Promise((resolve,reject) => {
bcrypt.compare(password,user.password,function(error,res){
if (error) { reject(error); }
resolve(res);
})
})
,
您的问题是您以错误的方式使用 bcrypt.hash
。
似乎您提供了这种方法的密钥,而您不应提供。
此方法接受要散列的值和 saltRounds
。
所以您基本上需要将您的注册 API 代码更改为:
router.post("/register",body("email").isEmail(),body("password").isLength({ min: 5 }),body("username").isLength({ min: 1 }),async (req,res) => {
const { email,username,password } = req.body
const errors = validationResult(req);
const saltRounds = 10;
try {
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() })
}
//check if the user exist
const duplicated = await User.findOne({ email })
if (duplicated) { return res.status(401).json({ "err": "Email is taken" }) }
const user = new User({ username,email,password })
//crypt pass
user.password = bcrypt.hashSync(password,saltRounds);
//generate token with jwt
const payload = {
id: user.id
}
jwt.sign({
payload,},process.env.jwtSecret,{ expiresIn: '999h' },(err,token) => { console.log(token) });
//save the user
await user.save()
res.status(200).send("User Stored")
} catch (error) {
res.status(500).send(error.body)
}
}
更具体地说,您使用以下方式存储密码:
user.password = bcrypt.hashSync(password,saltRounds);