sequelize promise always return false
sequelize promise always return false
我正在创建一个反应本机应用程序。
流程是这样的,客户必须输入电子邮件和密码才能注册,数据将保存在数据库中。在保存数据之前,我使用了预挂钩 beforeValidate 使用 bcrypt 对密码进行哈希处理。
到这里为止,一切正常,但当 instanceMethod comparePassword 做出承诺时,我似乎无法 return 正确。
我有一个客户模型 Customer.js 文件如下:
const Sequelize = require('sequelize');
const bcrypt = require('bcrypt');
const db = require('../config/database');
const Customer = db.define('customer', {
id : {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
email : {
type: Sequelize.STRING,
unique: true,
allowNull: false
},
password : {
type: Sequelize.STRING,
allowNull: false
},
createdAt : {
type: Sequelize.NOW
},
updatedAt : {
type: Sequelize.NOW
}
}, {
hooks: {
afterValidate: (customer) => {
customer.password = bcrypt.hashSync(customer.password, 10);
}
},
instanceMethods: {
comparePassword: (candidatePassword) => {
return new Promise((resolve, reject) => {
bcrypt.compareSync(candidatePassword, this.password, (err, isMatch) => {
if(err) {
return reject(err);
}
if(!isMatch) {
return reject(false);
}
resolve(true);
});
});
}
}
});
module.exports = Customer;
和如下 authRoutes.js 文件的片段:
router.post('/login', async (req, res) => {
const { email, password } = req.body;
if ( !email || !password ) {
return res.status(422).send({error: 'Must provide email and password!'});
}
const customer = await Customer.findOne({ where: {email} });
if(!customer) {
return res.status(422).send({error: '1. Invalid email or password!'});
}
try {
await customer.comparePassword(password);
const token = jwt.sign({ email }, 'MY_SECRET_KEY');
res.send({ email, token });
} catch(err) {
return res.status(422).send({error: '2. Invalid email or password!'});
}
});
没有任何错误或任何错误,但它总是会捕获“2. 无效的电子邮件或密码”错误,即使我输入了正确的凭据。任何形式的帮助表示赞赏。谢谢。
我创建了一个函数 (comparePassword) 来比较密码和散列密码,它使用 bcrypt 来比较密码。
const bcrypt = require('bcryptjs');
const customer = await Customer.findOne({ where: { email } });
const comparePassword = (hashedPassword, password) => {
return bcrypt.compareSync(password, hashedPassword);
};
try {
if (!comparePassword(customer.password, password) {
return res.status(422).send({ error: '2. Invalid email or password!' });
}
else {
const token = jwt.sign({ email }, 'MY_SECRET_KEY');
return res.status(200).send({ email, token });
}
} catch (err) {
console.log(err)
return res.status(500).send({ error: 'something bad happened on server' });
}
Customer
在 Sequelize 4+ 中可以定义为 class。然后可以将实例方法添加为常规 class 实例方法。
class Customer extends Sequelize.Model {
static table_schema = {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
...
}
static table_options = {
...
}
static init(sequelize){
return super.init(this.table_schema, { this.table_options, ...sequelize })
}
static associate(models) {
}
async comparePassword(candidatePassword){
return bcrypt.compare(candidatePassword, this.password)
}
}
Customer.addHook('afterValidate', async function(customer){
customer.password = await bcrypt.hash(customer.password, 10);
})
那么你应该可以在你的路由中使用异步 comparePassword
函数,类似于
router.post('/login', async (req, res) => {
try {
const { email, password } = req.body;
if ( !email || !password ) {
return res.status(422).send({error: 'Must provide email and password!'});
}
const customer = await Customer.findOne({ where: {email} });
if (!customer) {
console.log('Failed login [%s] not found', email)
return res.status(422).send({error: 'Invalid email or password!'});
}
const auth = await customer.comparePassword(password);
if (!auth) {
console.log('Failed login [%s] bad password', email)
return res.status(422).send({error: 'Invalid email or password!'});
}
const token = jwt.sign({ email }, 'MY_SECRET_KEY');
res.send({ email, token });
}
catch(err) {
console.error('Failed to process request', err)
return res.status(500).send({error: 'Internal Server Error'});
}
});
我正在创建一个反应本机应用程序。
流程是这样的,客户必须输入电子邮件和密码才能注册,数据将保存在数据库中。在保存数据之前,我使用了预挂钩 beforeValidate 使用 bcrypt 对密码进行哈希处理。
到这里为止,一切正常,但当 instanceMethod comparePassword 做出承诺时,我似乎无法 return 正确。
我有一个客户模型 Customer.js 文件如下:
const Sequelize = require('sequelize');
const bcrypt = require('bcrypt');
const db = require('../config/database');
const Customer = db.define('customer', {
id : {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
email : {
type: Sequelize.STRING,
unique: true,
allowNull: false
},
password : {
type: Sequelize.STRING,
allowNull: false
},
createdAt : {
type: Sequelize.NOW
},
updatedAt : {
type: Sequelize.NOW
}
}, {
hooks: {
afterValidate: (customer) => {
customer.password = bcrypt.hashSync(customer.password, 10);
}
},
instanceMethods: {
comparePassword: (candidatePassword) => {
return new Promise((resolve, reject) => {
bcrypt.compareSync(candidatePassword, this.password, (err, isMatch) => {
if(err) {
return reject(err);
}
if(!isMatch) {
return reject(false);
}
resolve(true);
});
});
}
}
});
module.exports = Customer;
和如下 authRoutes.js 文件的片段:
router.post('/login', async (req, res) => {
const { email, password } = req.body;
if ( !email || !password ) {
return res.status(422).send({error: 'Must provide email and password!'});
}
const customer = await Customer.findOne({ where: {email} });
if(!customer) {
return res.status(422).send({error: '1. Invalid email or password!'});
}
try {
await customer.comparePassword(password);
const token = jwt.sign({ email }, 'MY_SECRET_KEY');
res.send({ email, token });
} catch(err) {
return res.status(422).send({error: '2. Invalid email or password!'});
}
});
没有任何错误或任何错误,但它总是会捕获“2. 无效的电子邮件或密码”错误,即使我输入了正确的凭据。任何形式的帮助表示赞赏。谢谢。
我创建了一个函数 (comparePassword) 来比较密码和散列密码,它使用 bcrypt 来比较密码。
const bcrypt = require('bcryptjs');
const customer = await Customer.findOne({ where: { email } });
const comparePassword = (hashedPassword, password) => {
return bcrypt.compareSync(password, hashedPassword);
};
try {
if (!comparePassword(customer.password, password) {
return res.status(422).send({ error: '2. Invalid email or password!' });
}
else {
const token = jwt.sign({ email }, 'MY_SECRET_KEY');
return res.status(200).send({ email, token });
}
} catch (err) {
console.log(err)
return res.status(500).send({ error: 'something bad happened on server' });
}
Customer
在 Sequelize 4+ 中可以定义为 class。然后可以将实例方法添加为常规 class 实例方法。
class Customer extends Sequelize.Model {
static table_schema = {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
...
}
static table_options = {
...
}
static init(sequelize){
return super.init(this.table_schema, { this.table_options, ...sequelize })
}
static associate(models) {
}
async comparePassword(candidatePassword){
return bcrypt.compare(candidatePassword, this.password)
}
}
Customer.addHook('afterValidate', async function(customer){
customer.password = await bcrypt.hash(customer.password, 10);
})
那么你应该可以在你的路由中使用异步 comparePassword
函数,类似于
router.post('/login', async (req, res) => {
try {
const { email, password } = req.body;
if ( !email || !password ) {
return res.status(422).send({error: 'Must provide email and password!'});
}
const customer = await Customer.findOne({ where: {email} });
if (!customer) {
console.log('Failed login [%s] not found', email)
return res.status(422).send({error: 'Invalid email or password!'});
}
const auth = await customer.comparePassword(password);
if (!auth) {
console.log('Failed login [%s] bad password', email)
return res.status(422).send({error: 'Invalid email or password!'});
}
const token = jwt.sign({ email }, 'MY_SECRET_KEY');
res.send({ email, token });
}
catch(err) {
console.error('Failed to process request', err)
return res.status(500).send({error: 'Internal Server Error'});
}
});