我正在开发一个 Node.js 项目,该项目涉及使用 JWT 和 bcrypt 进行用户身份验证。我能够成功注册用户,但是当我尝试使用相同的密码登录时,出现密码不匹配错误。这是我的注册和登录功能的代码:
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const User = require('../models/User');
// Register a new user
const register = async (req, res, next) => {
const { username, email, password, role = 'student' } = req.body;
const saltRounds = 10;
try {
const hashedPassword = await bcrypt.hash(password, saltRounds);
const user = new User({ username, email, password: hashedPassword, role });
await user.save();
res.json({ message: 'Registration successful' });
} catch (error) {
next(error);
}
};
// Login with an existing user
const login = async (req, res, next) => {
const { username, password } = req.body;
try {
console.log('Received login request:', req.body);
if (!username || !password) {
return res.status(400).json({ message: 'Username and password are required' });
}
const user = await User.findOne({ username });
if (!user) {
console.log('User not found');
return res.status(404).json({ message: 'User not found' });
}
console.log('Stored hashed password:', user.password);
const passwordMatch = await bcrypt.compare(password, user.password);
console.log('Password match:', passwordMatch);
if (!passwordMatch) {
console.log('Password mismatch');
return res.status(401).json({ message: 'Incorrect password' });
}
const secretKey = process.env.SECRET_KEY || 'your-hardcoded-secret-key';
const token = jwt.sign({ userId: user._id }, secretKey, {
expiresIn: '1h'
});
res.json({ token });
} catch (error) {
console.error('Error logging in:', error);
res.status(500).json({ message: 'Error logging in' });
}
};
module.exports = { register, login };
我尝试注册并使用相同的密码登录,但收到“密码错误”错误。以下是一些有助于排除故障的详细信息:
在注册过程中,我使用 bcrypt 对密码进行哈希处理。 在登录过程中,我使用 bcrypt.compare 将纯密码与存储在数据库中的哈希密码进行比较。 我正在使用 JWT 的硬编码密钥,因为我在使用 .env 文件时遇到问题。 调试输出:
Received login request: { username: 'safiiii', password: 'safi123' }
Stored hashed password: $2b$10$yt1UcY4zNZujN1OIYjorQuqPVvDfgfRwV218Biw4gH.k0tbzXk.MK
Password match: false
Password mismatch
Received login request: { username: 'safiiii', password: 'safi123' }
Stored hashed password: $2b$10$yt1UcY4zNZujN1OIYjorQuqPVvDfgfRwV218Biw4gH.k0tbzXk.MK
Password match: false
Password mismatch
问题:
什么原因可能导致登录时密码不匹配? 我该如何解决这个问题? 附加信息:
Node.js 版本:14.x Bcrypt版本:5.0.1 智威汤逊版本:8.5.1 数据库:MongoDB 任何帮助将不胜感激!
我对 bcrypt 也有同样的问题。我正在使用这个方法:
public async signIn(email: string, pass: string): Promise<{ access_token: string }> {
this.logger.log(`email and password from controller signIn(): ${email} - ${pass}`)
try {
const { user, found } = await this.usersService.findOneByEmail(email);
if(!found || !user) throw new UnauthorizedException('Invalid credentials');
this.logger.log(`Hash password stored: ${user.password}`);
this.logger.log(`Password provided: ${pass}`);
const isPasswordMatching = await bcrypt.compare(pass, user.password);
this.logger.log(Resultado da comparação da senha: ${isPasswordMatching});
if (!isPasswordMatching) throw new UnauthorizedException('Invalid credentials')
const payload: AccessTokenPayload = {
sub: user.id,
email: user.email,
};
const accessToken = await this.jwtService.signAsync(payload, {
secret: this.configService.get<string>('JWT_SECRET'),
expiresIn: this.configService.get<string>('EXPIRES_IN')
});
return { access_token: accessToken };
} catch(error) {
this.logger.error(`Erro no método signIn()`, error.message);
throw error;
}
}
错误是我提供的密码无效。我使用的是 bycrpt 版本 5.1.1,数据库是 PostgreSQL。
然后,我尝试使用compare()的回调版本,并更改了使用这个的方法:
bcrypt.compare(pass, user.password, (err) => {
console.log("erro: ", err.message);
});
经过修改,一切正常!我不知道为什么,但这也许可以解决您的问题。