Nodejs bcrypt比较无法正常工作
Posted
技术标签:
【中文标题】Nodejs bcrypt比较无法正常工作【英文标题】:Nodejs bcrypt compare not working properly 【发布时间】:2019-07-10 22:30:42 【问题描述】:我正在使用 apollo 构建一个带有节点 qraphQl 的应用程序,我正在尝试创建一个登录页面,但在注册并尝试登录后,我的 bcrypt 将始终返回 false,
在我的用户模型中
import bcrypt from 'bcryptjs';
const user = (sequelize, DataTypes) =>
const User = sequelize.define('user',
id:
type: DataTypes.INTEGER,
autoIncrement: true,
unique: true,
primaryKey: true,
field: 'id'
,
fullname: DataTypes.STRING,
username:
type: DataTypes.STRING,
allowNull: false,
validate:
notEmpty: true,
,
,
email:
type: DataTypes.STRING,
allowedNull: false,
validate:
notEmpty: true,
isEmail: true,
,
password:
type: DataTypes.STRING,
allowedNull: false,
validate:
notEmpty: true,
len: [7, 42],
,
,
role:
type: DataTypes.ENUM,
values: ['ADMIN', 'INSTRUCTOR', 'STUDENT'],
defaultValue: 'STUDENT'
);
User.beforeCreate(async function(user)
user.password = await user.generatePasswordHash(user)
);
User.beforeSave(async function(user)
user.password = await user.generatePasswordHash(user)
);
User.prototype.generatePasswordHash = async function(user)
const saltRounds = 10;
return await bcrypt.hash(user.password, saltRounds)
;
User.prototype.validatePassword = async function(password)
console.log(this.password)
const theReturn = await bcrypt.compare(password, this.password)
console.log(theReturn)
return theReturn;
;
User.associate = models =>
User.hasMany(models.Message, onDelete: 'CASCADE' );
;
User.findByLogin = async login =>
let user = await User.findOne(
where: username: login ,
);
if (!user)
user = await User.findOne(
where: email: login ,
);
return user;
;
return User;
;
export default user;
在我的用户解析器中,这里是代码
import combineResolvers from 'graphql-resolvers';
import Joi from 'joi'
import isAuthenticated, isAdmin from './authorization';
import SignUp, SignIn from '../functions/joi'
import createToken from '../functions/jwt'
export default
Mutation:
signUp: async (parent, username, fullname, email, password, Rpassword, models, secret ) =>
if(password !== Rpassword)
return new Error('Password did not match')
var thejoi = username, fullname, email, password
const checkUserEm = await models.User.find( where: email: email )
if (checkUserEm)
return new Error('Email address already Exist')
const checkUserUs = await models.User.find( where: username: username )
if (checkUserUs)
return new Error('Username already Exist')
await Joi.validate(thejoi, SignUp, abortEarly:false)
const user = await models.User.create(
username,
fullname,
email,
password,
role:'STUDENT'
);
return token: createToken(user) ;
,
signIn: async (parent, login, password , models, secret , ) =>
var varrh = password
await Joi.validate(varrh, SignIn, abortEarly:false)
const user = await models.User.findByLogin(login);
if (!user)
return new Error('No user found with this login credentials.');
const isValid = await user.validatePassword(password);
if (!isValid)
return new Error('Invalid password .');
return token: createToken(user) ;
,
User:
messages: async (user, args, models ) =>
return await models.Message.findAll(
where:
userId: user.id
);
,
,
当我尝试注册时,它成功了,它将密码存储在数据库中,但是当我尝试登录时,我收到了这个错误消息
"errors": [
"message": "Invalid password .",
"locations": [
"line": 2,
"column": 3
],
"path": [
"signIn"
],
"extensions":
"code": "INTERNAL_SERVER_ERROR",
"exception":
"stacktrace": [
"Error: Invalid password .",
" at signIn (C:\\Users\\De Stone Of David\\Desktop\\node projects\\vue\\cybersec\\server\\src\\resolvers\\user.js:65:16)"
]
],
"data": null
在控制台中我得到了这个
Executing (default): INSERT INTO `users` (`id`,`fullname`,`username`,`email`,`password`,`role`,`createdAt`,`updatedAt`) VALUES (DEFAULT,'nsalknlsa','stones4semper','Eloike95@gmail.com','$2a$10$eX8zvI7/EJv6N.2RzbBh9e.qKoJXtmDNDw22nAY6dixTi4btWCB6G','STUDENT','2019-02-17 09:51:44','2019-02-17 09:51:44');
Executing (default): SELECT `id`, `fullname`, `username`, `email`, `password`, `role`, `createdAt`, `updatedAt` FROM `users` AS `user` WHERE `user`.`username` = 'Eloike95@gmail.com' LIMIT 1;
Executing (default): SELECT `id`, `fullname`, `username`, `email`, `password`, `role`, `createdAt`, `updatedAt` FROM `users` AS `user` WHERE `user`.`email` = 'Eloike95@gmail.com' LIMIT 1;
$2a$10$eX8zvI7/EJv6N.2RzbBh9e.qKoJXtmDNDw22nAY6dixTi4btWCB6G
false
请我真的很困惑,因为它假设可以工作,我搜索了谷歌但它没有帮助我,我该如何解决这个问题?提前致谢。
【问题讨论】:
通过同时连接 beforeCreate 和 beforeSave,您不是对密码进行两次散列吗?喜欢密码 -> 哈希(密码) -> 哈希(哈希(密码))?如果是这样的话,原版永远不会匹配?尝试注释掉其中一个钩子,看看它是否有任何改变。 实际上,我会摆脱beforeSave
钩子,因为您显然不想在用户每次更新信息时都重新散列用户密码。
【参考方案1】:
好的,所以我遇到了同样的问题,解决方案是这样的。
在您的用户模型文件中
线:-const theReturn = await bcrypt.compare(password, this.password)
这里的密码已经用compare
或compareSync
进行了哈希处理,第一个参数应该是你在登录表单中输入的unhashed密码。
第二个参数是一个已经散列的密码,您想将其与您的数据进行比较。
因此,您所要做的就是不对密码进行哈希处理,因为您已经对其进行哈希处理,然后将其发送到比较函数,它会被哈希两次。所以你得到一个无效的密码。
仅供参考,compare
用于并且需要处理 Promise;并且使用了compareSync
,没有Promise。此外,compareSync
返回一个布尔值。
希望对你有帮助,谢谢!
【讨论】:
以上是关于Nodejs bcrypt比较无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
Bcrypt Elastic beanstalk nodejs 部署