Node.js使用bcrypt加密密码后比对返回false的问题排查
Node.js中bcrypt密码比对始终返回false问题排查
问题现象
在Node.js项目中使用bcrypt加密用户密码存入MySQL数据库后,登录时密码比对始终返回false。
初始版本代码
密码加密存储代码
// con.escapeId(sorter); //ICI CRYPTAGE DE motDePasse bcrypt motDePasse = bcrypt.hashSync(motDePasse, 10); //var sql = "INSERT INTO `users` (`id`, `first_name`,`last_name`,`telephone`,`user_name`,`password`,`adresseMail`,`rue`,`codePostal`,`ville`,`confirmation`) VALUES (NULL, '"+con.escapeId(nom)+"','"+con.escapeId(prenom)+"','"+con.escapeId(telephone)+"','"+con.escapeId(pseudo)+"','"+con.escapeId(motDePasse)+"','"+con.escapeId(adresseMail)+"','"+con.escapeId(rue)+"','"+con.escapeId(codePostal)+"','"+con.escapeId(ville)+"','"+confirmation+"')"; var sql = "INSERT INTO `users` (`id`, `first_name`,`last_name`,`telephone`,`user_name`,`password`,`adresseMail`,`rue`,`codePostal`,`ville`,`confirmation`) VALUES (NULL, '"+nom+"','"+prenom+"','"+telephone+"','"+pseudo+"','"+motDePasse+"','"+adresseMail+"','"+rue+"','"+codePostal+"','"+ville+"','"+confirmation+"')"; con.query(sql, function (err, result) { if (err) throw err; console.log("1 record inserted");
密码校验代码
con.query("SELECT * FROM `users` WHERE `user_name`='"+login+"'" , function (err, result) { //con.query("SELECT * FROM `users` WHERE `user_name`='"+login+"' and password = '"+password+"'" , function (err, result) { if (err) throw err; const comparison = bcrypt.compareSync(password, result[0].password); console.log("comparison:"+comparison);
第一次优化后代码
调整为bcrypt异步接口、SQL参数化写法:
优化后加密存储代码
/ICI CRYPTAGE DE motDePasse bcrypt bcrypt.genSalt(10, function(err, salt) {//--- bcrypt.hash(motDePasse, salt, function(err, hash) { console.log("hash:"+hash); var sql = "INSERT INTO `users` (`id`, `first_name`,`last_name`,`telephone`,`user_name`,`password`,`adresseMail`,`rue`,`codePostal`,`ville`,`confirmation`) VALUES (NULL, '"+nom+"','"+prenom+"','"+telephone+"','"+pseudo+"','"+hash+"','"+adresseMail+"','"+rue+"','"+codePostal+"','"+ville+"','"+confirmation+"')";
优化后校验代码
con.query("SELECT * FROM `users` WHERE `user_name`= ?" ,[login], function (err,result) { //con.query("SELECT * FROM `users` WHERE `user_name`='"+login+"' and password = '"+password+"'" , function (err, result) { if (err) throw err; console.log("password:"+password); bcrypt.compare(password, result[0].password, function(err, result) { console.log("result:"+result); });
根因定位
优化后测试发现,直接将数据库取出的哈希值硬编码到代码中比对可以正常返回true,排除数据库存储逻辑异常,最终排查到问题出在密码预处理环节:
let motDePasse=req.body.motDePasse.replace(/<[^>]+>/g, '');
该正则会将密码中所有符合HTML标签格式的内容替换为空,导致加密的密码和用户登录时输入的原始密码不一致,删除这段预处理代码后功能恢复正常。
该排查过程可作为同类问题的参考。
内容的提问来源于stack exchange,提问作者Laurent Gevaert
相关产品推荐
相关产品推荐

