能否在bcrypt哈希函数内创建User对象?两种注册写法有何区别?
两种实现写法的差异说明
首先你的「一次性实现」思路本身是合理的,但是你写的代码存在一个明显的bug,除此之外这种实现方式甚至比教程里的写法更有优势。
你写的代码存在的核心问题
你在创建User实例的时候,直接传入了hash字段:
let newUser = new User({ name, username, hash, // 这里的字段名是错误点 email, });
绝大多数业务的Mongoose Schema里,存储密码的字段都是命名为password,如果你直接传hash字段,哈希后的密码根本不会存入数据库对应字段,后续登录校验密码的时候会直接失败。只要把这里改成password: hash,你的写法就是完全可用的。
两种写法的优劣势对比
教程里先创建实例再替换密码的写法
- 优点:对新手友好,创建实例的时候直接传入明文
password,不会出现字段名匹配错误的低级问题,符合新手从上到下写代码的逻辑 - 缺点:明文密码会在User实例上短暂停留,存在极小的内存泄露泄露明文的风险,而且多了一次对象属性修改的操作
你提出的先算哈希再创建实例的写法
- 优点:性能更好,不需要创建实例后再修改属性,同时明文密码不会挂载到User实例上,安全系数更高
- 缺点:需要明确注意字段名的匹配,新手很容易写错字段名导致功能异常
额外优化建议
两种写法用的都是bcrypt的回调写法,嵌套层级深可读性差,现在更推荐用async/await的写法重构,同时不要直接throw err,最好捕获错误后返回明确的500错误给前端,避免直接抛出错误导致服务崩溃。
内容的提问来源于stack exchange,提问作者Darren Seet
相关产品推荐
相关产品推荐

