JS登录认证模块报错:ReferenceError: Cannot access 'password' before initialization
问题描述
使用JS开发登录认证模块时,密码验证环节始终报错,用户存在性检查功能正常,但登录返回如下结果:
{ "status": false, "message": "Failed to login" }
报错信息
The error: ReferenceError: Cannot access 'password' before initialization at login (file:///C:/Users/usuario/Desktop/Proyectos%20VS/DoctorAppointmentBooking/backend/Controllers/authController.js:100:56) at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
问题代码行(第100行)
const isPasswordMatched = await bcrypt.compare(password, user.password);
完整代码
import User from '../models/UserSchema.js' import Doctor from '../models/DoctorSchema.js' import jwt from 'jsonwebtoken' import bcrypt from 'bcryptjs' const generateToken = user=>{ return jwt.sign( {id: user._id, role: user.role}, process.env.JWT_SECRET_key, { expiresIn: "15d", }) } export const login = async(req, res) => { const { email, password } = req.body; try{ let user = null; const patient = await User.findOne({ email }); const doctor = await Doctor.findOne({ email }); if(patient){ user = patient } if (doctor){ user = doctor } //check if user exists or not if(!user){ return res.status(404).json({message: "User not found."}) } //check password const isPasswordMatched = await bcrypt.compare(password, user.password); if(!isPasswordMatched){ return res .status(400) .json({status: false, message: "Incorrect credentials"}) } //get token const token = generateToken(user); const {password, role, appointments, ...rest} = user._doc res .status(200) .json({status: true, message: "Successfully login", token, data:{...rest}, role}); } catch (err){ return res .status(500) .json({status: false, message: "Failed to login"}) } }
问题原因
login函数的同一作用域内,先后用const声明了两个同名的password变量:
- 开头从
req.body解构得到的const { email, password } = req.body; - 后续处理响应时解构
user._doc的const {password, role, appointments, ...rest} = user._doc
JavaScript中,同一作用域内不允许用const重复声明变量,且const声明的变量会被提升到作用域顶部但处于暂时性死区。引擎会判定第100行使用的password是后面未初始化的变量,因此抛出错误。
解决方案
修改解构user._doc时的变量名,避免和从req.body获取的password重名,或者直接忽略该字段(更推荐,因为不需要返回密码):
// 方案1:重命名变量 const {password: userPassword, role, appointments, ...rest} = user._doc // 方案2:直接忽略password字段 const {role, appointments, ...rest} = user._doc
修改后,第100行的password会正确指向从请求体获取的密码值,密码验证环节即可正常执行。
内容的提问来源于stack exchange,提问作者Noelia khljk
相关产品推荐
相关产品推荐

