将 BCrypt 与 Sequelize 模型结合使用
Using BCrypt with Sequelize Model
我正在尝试将 bcrypt-nodejs
包与我的 sequelize 模型一起使用,并试图按照教程将哈希合并到我的模型中,但我在 generateHash
处遇到错误.我似乎无法弄清楚这个问题。有没有更好的方法来合并 bcrypt?
错误:
/Users/user/Desktop/Projects/node/app/app/models/user.js:26
User.methods.generateHash = function(password) {
^
TypeError: Cannot set property 'generateHash' of undefined
at module.exports (/Users/user/Desktop/Projects/node/app/app/models/user.js:26:27)
at Sequelize.import (/Users/user/Desktop/Projects/node/app/node_modules/sequelize/lib/sequelize.js:641:30)
型号:
var bcrypt = require("bcrypt-nodejs");
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('users', {
annotation_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.DATE,
field: 'first_name'
},
lastName: {
type: DataTypes.DATE,
field: 'last_name'
},
email: DataTypes.STRING,
password: DataTypes.STRING,
}, {
freezeTableName: true
});
User.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
User.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
return User;
}
方法 should be 在 sequelize.define
的 "options" 参数中提供
const bcrypt = require("bcrypt");
module.exports = function(sequelize, DataTypes) {
const User = sequelize.define('users', {
annotation_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.DATE,
field: 'first_name'
},
lastName: {
type: DataTypes.DATE,
field: 'last_name'
},
email: DataTypes.STRING,
password: DataTypes.STRING
}, {
freezeTableName: true,
instanceMethods: {
generateHash(password) {
return bcrypt.hash(password, bcrypt.genSaltSync(8));
},
validPassword(password) {
return bcrypt.compare(password, this.password);
}
}
});
return User;
}
其他选择: 使用 hook 和 bcrypt 异步模式
User.beforeCreate((user, options) => {
return bcrypt.hash(user.password, 10)
.then(hash => {
user.password = hash;
})
.catch(err => {
throw new Error();
});
});
a tutorial out there 介绍了如何获得使用挂钩和 bcrypt 的 sequelize/postgreSQL 身份验证系统。
写教程的人没有使用异步 hash/salt 方法;在用户 creation/instance 方法部分,他使用了以下代码:
hooks: {
beforeCreate: (user) => {
const salt = bcrypt.genSaltSync();
user.password = bcrypt.hashSync(user.password, salt);
}
},
instanceMethods: {
validPassword: function(password) {
return bcrypt.compareSync(password, this.password);
}
}
较新版本的 Sequelize 不喜欢以这种方式声明实例方法 - 许多人已经解释了如何解决这个问题(包括在原始教程中发帖的人):
原评论仍然使用了同步方法:
User.prototype.validPassword = function (password) {
return bcrypt.compareSync(password, this.password);
};
要使这些函数异步,您需要做的就是:
异步 beforeCreate bcrypt genSalt 和 genHash 函数:
beforeCreate: async function(user) {
const salt = await bcrypt.genSalt(10); //whatever number you want
user.password = await bcrypt.hash(user.password, salt);
}
User.prototype.validPassword = async function(password) {
return await bcrypt.compare(password, this.password);
}
在检查密码的登录路径中的 node.js 应用程序中,有一个 findOne 部分:
User.findOne({ where: { username: username } }).then(function (user) {
if (!user) {
res.redirect('/login');
} else if (!user.validPassword(password)) {
res.redirect('/login');
} else {
req.session.user = user.dataValues;
res.redirect('/dashboard');
}
});
您只需在此处添加单词 async
和 await
:
User.findOne({ where: { username: username } }).then(async function (user) {
if (!user) {
res.redirect('/login');
} else if (!await user.validPassword(password)) {
res.redirect('/login');
} else {
req.session.user = user.dataValues;
res.redirect('/dashboard');
}
});
Bcrypt 不再是节点的一部分,因此我将示例包含在新的加密模块中
我正在从一个工作项目中分享这段代码。
我的配置文件
require('dotenv').config();
const { Sequelize,DataTypes ,Model} = require("sequelize");
module.exports.Model = Model;
module.exports.DataTypes = DataTypes;
module.exports.sequelize = new Sequelize(process.env.DB_NAME,process.env.DB_USER_NAME, process.env.DB_PASSWORD, {
host: process.env.DB_HOST,
dialect: process.env.DB_DISELECT,
pool: {
max: 1,
min: 0,
idle: 10000
},
//logging: true
});
我的用户模型
const { sequelize, DataTypes, Model } = require('../config/db.config');
var crypto = require('crypto');
class USERS extends Model {
validPassword(password) {
var hash = crypto.pbkdf2Sync(password,
this.SALT, 1000, 64, `sha512`).toString(`hex`);
console.log(hash == this.PASSWORD)
return this.PASSWORD === hash;
}
}
USERS.init(
{
ID: {
autoIncrement: true,
type: DataTypes.BIGINT,
allowNull: false,
primaryKey: true
},
MOBILE_NO: {
type: DataTypes.BIGINT,
allowNull: false,
unique: true
},
PASSWORD: {
type: DataTypes.STRING(200),
allowNull: false
},
SALT: {
type: DataTypes.STRING(200),
allowNull: false
}
},
{
sequelize,
tableName: 'USERS',
timestamps: true,
hooks: {
beforeCreate: (user) => {
console.log(user);
user.SALT = crypto.randomBytes(16).toString('hex');
user.PASSWORD = crypto.pbkdf2Sync(user.PASSWORD, user.SALT,
1000, 64, `sha512`).toString(`hex`);
},
}
});
module.exports.USERS = USERS;
和授权控制器
const { USERS } = require('../../../models/USERS');
module.exports = class authController {
static register(req, res) {
USERS.create({
MOBILE_NO: req.body.mobile,
PASSWORD: req.body.password,
SALT:""
}).then(function (data) {
res.json(data.toJSON());
}).catch((err) => {
res.json({
error: err.errors[0].message
})
})
}
static login(req, res) {
var message = [];
var success = false;
var status = 404;
USERS.findOne({
where:{
MOBILE_NO: req.body.mobile
}
}).then(function (user) {
if (user) {
message.push("user found");
if(user.validPassword(req.body.password)) {
status=200;
success = true
message.push("You are authorised");
}else{
message.push("Check Credentials");
}
}else{
message.push("Check Credentials");
}
res.json({status,success,message});
});
}
}
我正在尝试将 bcrypt-nodejs
包与我的 sequelize 模型一起使用,并试图按照教程将哈希合并到我的模型中,但我在 generateHash
处遇到错误.我似乎无法弄清楚这个问题。有没有更好的方法来合并 bcrypt?
错误:
/Users/user/Desktop/Projects/node/app/app/models/user.js:26
User.methods.generateHash = function(password) {
^
TypeError: Cannot set property 'generateHash' of undefined
at module.exports (/Users/user/Desktop/Projects/node/app/app/models/user.js:26:27)
at Sequelize.import (/Users/user/Desktop/Projects/node/app/node_modules/sequelize/lib/sequelize.js:641:30)
型号:
var bcrypt = require("bcrypt-nodejs");
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('users', {
annotation_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.DATE,
field: 'first_name'
},
lastName: {
type: DataTypes.DATE,
field: 'last_name'
},
email: DataTypes.STRING,
password: DataTypes.STRING,
}, {
freezeTableName: true
});
User.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
User.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
return User;
}
方法 should be 在 sequelize.define
const bcrypt = require("bcrypt");
module.exports = function(sequelize, DataTypes) {
const User = sequelize.define('users', {
annotation_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.DATE,
field: 'first_name'
},
lastName: {
type: DataTypes.DATE,
field: 'last_name'
},
email: DataTypes.STRING,
password: DataTypes.STRING
}, {
freezeTableName: true,
instanceMethods: {
generateHash(password) {
return bcrypt.hash(password, bcrypt.genSaltSync(8));
},
validPassword(password) {
return bcrypt.compare(password, this.password);
}
}
});
return User;
}
其他选择: 使用 hook 和 bcrypt 异步模式
User.beforeCreate((user, options) => {
return bcrypt.hash(user.password, 10)
.then(hash => {
user.password = hash;
})
.catch(err => {
throw new Error();
});
});
a tutorial out there 介绍了如何获得使用挂钩和 bcrypt 的 sequelize/postgreSQL 身份验证系统。
写教程的人没有使用异步 hash/salt 方法;在用户 creation/instance 方法部分,他使用了以下代码:
hooks: {
beforeCreate: (user) => {
const salt = bcrypt.genSaltSync();
user.password = bcrypt.hashSync(user.password, salt);
}
},
instanceMethods: {
validPassword: function(password) {
return bcrypt.compareSync(password, this.password);
}
}
较新版本的 Sequelize 不喜欢以这种方式声明实例方法 - 许多人已经解释了如何解决这个问题(包括在原始教程中发帖的人):
原评论仍然使用了同步方法:
User.prototype.validPassword = function (password) {
return bcrypt.compareSync(password, this.password);
};
要使这些函数异步,您需要做的就是:
异步 beforeCreate bcrypt genSalt 和 genHash 函数:
beforeCreate: async function(user) {
const salt = await bcrypt.genSalt(10); //whatever number you want
user.password = await bcrypt.hash(user.password, salt);
}
User.prototype.validPassword = async function(password) {
return await bcrypt.compare(password, this.password);
}
在检查密码的登录路径中的 node.js 应用程序中,有一个 findOne 部分:
User.findOne({ where: { username: username } }).then(function (user) {
if (!user) {
res.redirect('/login');
} else if (!user.validPassword(password)) {
res.redirect('/login');
} else {
req.session.user = user.dataValues;
res.redirect('/dashboard');
}
});
您只需在此处添加单词 async
和 await
:
User.findOne({ where: { username: username } }).then(async function (user) {
if (!user) {
res.redirect('/login');
} else if (!await user.validPassword(password)) {
res.redirect('/login');
} else {
req.session.user = user.dataValues;
res.redirect('/dashboard');
}
});
Bcrypt 不再是节点的一部分,因此我将示例包含在新的加密模块中
我正在从一个工作项目中分享这段代码。
我的配置文件
require('dotenv').config();
const { Sequelize,DataTypes ,Model} = require("sequelize");
module.exports.Model = Model;
module.exports.DataTypes = DataTypes;
module.exports.sequelize = new Sequelize(process.env.DB_NAME,process.env.DB_USER_NAME, process.env.DB_PASSWORD, {
host: process.env.DB_HOST,
dialect: process.env.DB_DISELECT,
pool: {
max: 1,
min: 0,
idle: 10000
},
//logging: true
});
我的用户模型
const { sequelize, DataTypes, Model } = require('../config/db.config');
var crypto = require('crypto');
class USERS extends Model {
validPassword(password) {
var hash = crypto.pbkdf2Sync(password,
this.SALT, 1000, 64, `sha512`).toString(`hex`);
console.log(hash == this.PASSWORD)
return this.PASSWORD === hash;
}
}
USERS.init(
{
ID: {
autoIncrement: true,
type: DataTypes.BIGINT,
allowNull: false,
primaryKey: true
},
MOBILE_NO: {
type: DataTypes.BIGINT,
allowNull: false,
unique: true
},
PASSWORD: {
type: DataTypes.STRING(200),
allowNull: false
},
SALT: {
type: DataTypes.STRING(200),
allowNull: false
}
},
{
sequelize,
tableName: 'USERS',
timestamps: true,
hooks: {
beforeCreate: (user) => {
console.log(user);
user.SALT = crypto.randomBytes(16).toString('hex');
user.PASSWORD = crypto.pbkdf2Sync(user.PASSWORD, user.SALT,
1000, 64, `sha512`).toString(`hex`);
},
}
});
module.exports.USERS = USERS;
和授权控制器
const { USERS } = require('../../../models/USERS');
module.exports = class authController {
static register(req, res) {
USERS.create({
MOBILE_NO: req.body.mobile,
PASSWORD: req.body.password,
SALT:""
}).then(function (data) {
res.json(data.toJSON());
}).catch((err) => {
res.json({
error: err.errors[0].message
})
})
}
static login(req, res) {
var message = [];
var success = false;
var status = 404;
USERS.findOne({
where:{
MOBILE_NO: req.body.mobile
}
}).then(function (user) {
if (user) {
message.push("user found");
if(user.validPassword(req.body.password)) {
status=200;
success = true
message.push("You are authorised");
}else{
message.push("Check Credentials");
}
}else{
message.push("Check Credentials");
}
res.json({status,success,message});
});
}
}