GraphQL登录遇bcrypt错误‘Illegal arguments: string, function’排查
问题排查:GraphQL登录功能的bcrypt错误与变量未定义问题
问题描述
使用GraphQL实现注册/登录功能,注册流程正常,但登录时出现两个问题:
- 调用
loginUser时,if语句内使用user.model作为bcrypt.compare的参数,抛出错误:Illegal arguments: string, function - 改为
user.password后,又出现newUser未定义的错误
错误根源与修复方案
1. bcrypt参数错误(Illegal arguments: string, function)
原代码中bcrypt.compare(password, user.model)里的user.model是Mongoose模型的构造函数,并非用户的加密密码字段。注册时我们把加密密码存在了user.password字段,所以这里应该替换为user.password:
// 错误写法 if (user && (await bcrypt.compare(password, user.model))) { // 正确写法 if (user && (await bcrypt.compare(password, user.password))) {
2. newUser未定义错误
loginUser函数中没有声明newUser变量,你在生成JWT时错误引用了newUser._id,但此时已经从数据库查询到了user对象,应该使用user._id:
// 错误写法 const token = jwt.sign( { user_id: newUser._id, email }, "this is the secret", { expiresIn: "2h" } ); // 正确写法 const token = jwt.sign( { user_id: user._id, email }, "this is the secret", { expiresIn: "2h" } );
3. 额外问题:return语句中的res未定义
原代码最后返回{ id: res.id, ...res._doc },但loginUser里没有res变量,直接使用查询到的user对象即可,同时建议保存更新后的token到数据库:
// 先保存更新后的user await user.save(); // 正确返回 return { id: user.id, ...user._doc, };
修复后的完整loginUser resolver
async loginUser(_, { loginInput: { email, password } }) { const user = await User.findOne({ email }); if (!user) { throw new ApolloError("用户不存在", "User_Not_Found"); } const isPasswordValid = await bcrypt.compare(password, user.password); if (!isPasswordValid) { throw new ApolloError("密码错误", "Invalid_Password"); } const token = jwt.sign( { user_id: user._id, email }, "this is the secret", { expiresIn: "2h", } ); user.token = token; await user.save(); return { id: user.id, ...user._doc, }; }
内容的提问来源于stack exchange,提问作者ChrisWill303
相关产品推荐
相关产品推荐

