ExpressJS+bcrypt登录校验时如何从MySQL查询结果提取密码哈希字符串
核心原因
mysql2 promise 模式的 query() 接口返回固定二元结构数组:
- 数组第一项:查询命中的所有行组成的结果集,本身是数组类型,即使只匹配到1条记录,也会被包裹在该数组内
- 数组第二项:查询相关的字段元数据
原有代码仅取到了第一层的结果集数组,没有进一步读取数组内的具体行对象,因此无法获取到字符串格式的密码哈希值。另外原有代码直接拼接用户输入到SQL语句存在SQL注入风险,需要同步修复。
修正代码
使用解构语法直接取出结果集,改用参数化查询规避注入风险,增加用户不存在的边界判断,正确读取哈希值:
// 采用参数化查询,禁止直接拼接用户输入到SQL语句 const [userRows] = await db.promise().query( 'SELECT password FROM USERS WHERE email = ?', [req.body.email] ); // 未查询到对应用户直接返回校验失败 if (userRows.length === 0) { return res.send('WRONG!'); } // 取第一条匹配记录的password字段,即为纯字符串格式的bcrypt哈希 const storedHash = userRows[0].password; const compareResult = bcrypt.compareSync(req.body.password, storedHash); res.send(compareResult ? 'SUCCESS!' : 'WRONG!');
注意:如果email字段设置了唯一约束,查询结果最多只会返回1条记录,直接取索引0的行对象即可。
内容的提问来源于stack exchange,提问作者Ben Böckmann
相关产品推荐
相关产品推荐

