Node.js登录输入未注册邮箱报Cannot read property 'password' of null如何解决
问题原因
你的代码报错是因为JavaScript按顺序逐行执行,当查询的邮箱不存在、result为null时,会先执行const isPasswordCorrect = bcrypt.compareSync(reqBody.password, result.password)这行代码,此时访问result.password直接触发类型错误,后续的if判断逻辑根本没有执行机会。
解决方案
你不需要拆分错误提示,只要调整代码执行顺序、避免在result为null时访问它的属性,同时保持两种异常场景返回相同的提示即可,参考实现如下:
方案1:通过前置判断兼容null场景
module.exports.login = (reqBody) => { return User.findOne({email: reqBody.email}).then((result, error) => { // 仅当result存在时才执行密码比对,否则直接标记为校验不通过 const isPasswordCorrect = result ? bcrypt.compareSync(reqBody.password, result.password) : false; if (result == null || isPasswordCorrect == false) { return "邮箱或密码错误"; } else { return {access: auth.createAccessToken(result.toObject())}; } }); }
方案2:使用可选链语法简化判断
如果你的运行环境支持ES2020+语法,可以用可选链操作符?.进一步简化代码:
module.exports.login = (reqBody) => { return User.findOne({email: reqBody.email}).then((result, error) => { // result为null时result?.password返回undefined,和空字符串比对必然返回false const isPasswordCorrect = bcrypt.compareSync(reqBody.password, result?.password ?? ''); if (result == null || !isPasswordCorrect) { return "邮箱或密码错误"; } return {access: auth.createAccessToken(result.toObject())}; }); }
以上两种方案都不会泄露“邮箱是否注册”的信息,完全符合你统一返回错误提示的需求,同时规避了空属性访问报错。
内容的提问来源于stack exchange,提问作者quielfala
相关产品推荐
相关产品推荐

