使用 bcryptjs 将散列密码保存到数据库时出错

Posted

技术标签:

【中文标题】使用 bcryptjs 将散列密码保存到数据库时出错【英文标题】:error saving hashed password to db using bcryptjs 【发布时间】:2018-10-05 07:19:05 【问题描述】:

我正在使用 node.js 和 bcryptjs 注册一个新用户并将他们的姓名/电子邮件/密码保存到 mlab 中的 mongoDB。

这是我的代码

const express = require("express");
const router = express.Router();
const gravatar = require("gravatar");
const bcrypt = require("bcryptjs");

// Load User model
const User = require("../../models/User");

// @route   GET api/users/test
// @desc    Tests users route
// @access  Public
router.get("/test", (req, res) => res.json( msg: "Users Works" ));

// @route   GET api/users/register
// @desc    Register user
// @access  Public
router.post("/register", (req, res) => 
  User.findOne( email: req.body.email ).then(user => 
    if (user) 
      return res.status(400).json( email: "Email already exists" );
     else 
      const avatar = gravatar.url(req.body.email, 
        s: "200", // Size
        r: "pg", // Rating
        d: "mm" // Default
      );

      const newUser = new User(
        name: req.body.name,
        email: req.body.email,
        avatar,
        password: req.body.password
      );

      bcrypt.genSalt(10, (err, salt) => 
        bcrypt.hash(newUser.password, salt, (err, hash) => 
          if (err) throw err;
          newUser.password = hash;
          newUser
            .save()
            .then(user => res.json(user))
            .catch(err => console.log(err));
        );
      );
    
  );
);

// @route   GET api/users/login
// @desc    Login User / Returning JWT Token
// @access  Public

module.exports = router;

如果我注释掉第 37 行“if(err) throw err;”我可以存储用户凭据,但不会存储密码(使用邮递员)

我收到的错误是..

错误:非法参数:未定义,字符串 在 _async (C:\Users\Cody\Desktop\DevSoc\node_modules\bcryptjs\dist\bcrypt.js:214:46) 在 Object.bcrypt.hash (C:\Users\Cody\Desktop\DevSoc\node_modules\bcryptjs\dist\bcrypt.js:220:13) 在 bcrypt.genSalt (C:\Users\Cody\Desktop\DevSoc\routes\api\users.js:36:16) 在 Immediate._onImmediate (C:\Users\Cody\Desktop\DevSoc\node_modules\bcryptjs\dist\bcrypt.js:153:21) 在 runCallback (timers.js:789:20) 在 tryOnImmediate (timers.js:751:5) 在 processImmediate [as _immediateCallback] (timers.js:722:5)

这是从哪里来的?我的代码中看不到错误。

谢谢

【问题讨论】:

newUser.password 包含什么?实际上将其记录在请求中并找出答案。错误表明这是undefined 你是对的,它回来了 undefined.. 现在我正试图找出原因。 req.body 开始。记录它,然后回顾正在发出的请求,如果它甚至不存在。检查您是否设置了正文解析器。如果这些都不适用,那么很可能是您的模型有问题。可能掩盖了一个字段或类似的。 错误出现在我的模型中。无法解释这给我带来的挫败感。感谢朋友的帮助 【参考方案1】:

您似乎将undefined 密码传递给bcrypt.hash

为了确保它不会到达那个点,添加更早的验证,可能在 POST 路由的第一行:

router.post("/register", (req, res) => 
  const email, password = req.body
  if (!email || !password) 
    return res.send('Must include email and password')
  
  ...
)

【讨论】:

错误实际上是在我的模型中,但你是正确的 newUser.password is undefined @4cody 那么你为什么接受这个答案呢!显然,您的问题不包括在模型中显示错误(可能是不同的名称)的代码部分,显然这并没有给出原因。您真的应该删除问题或至少更新并自行回答。在当前状态下,接受一个并非真正解决方案的答案只会误导他人。 他给出的答案是可以接受的。但我明白你在说什么,请注意。

以上是关于使用 bcryptjs 将散列密码保存到数据库时出错的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Apache Shiro 将散列密码存储到数据库中?

如何使 Vue.js 将散列密码发布到 Django REST API AbstractBaseUser 自定义模型?

SQL Server - 如何将散列密码插入表?

shiro学习三

多个 JWT 的匹配哈希 JWT

PHP 去散列密码