使用 bcrypt 和 SQLite3 进行登录身份验证
Login Authentication with bcrypt and SQLite3
我目前正在构建一个带有 Nodejs/Express 后端的 React 应用程序,并尝试实现登录身份验证。
我用姓名、电子邮件、密码注册用户,并用 bcrypt 散列密码:
router.post('/register', async (req, res) => {
// Hashing
const salt = await bcrypt.genSalt(10)
const hashedPassword = await bcrypt.hash(req.body.regpassword, salt)
// Validate
const {error} = Joi.validate(req.body, schema)
var data = {
regname: req.body.regname,
regemail: req.body.regemail,
regpassword : hashedPassword
}
var sql ='INSERT INTO Users (regname, regemail, regpassword) VALUES (?,?,?)'
var params =[data.regname, data.regemail, data.regpassword]
db.run(sql, params, function (err, result) {
if (error){
res.status(400).send(error.details[0].message);
return;
}
res.json({
"answer": "Success",
})
res.status(200)
});
})
这很好用。但是我的 /login 路由不起作用:
router.post('/login', (req, res, next) => {
let sql = `SELECT * FROM Users WHERE regname = "${req.body.regname}" AND regpassword = "${req.body.regpassword}"`;
var x;
db.all(sql, (err, rows) => {
if (err) {
next(err);
return;
}
if (!rows) {
res.status(400);
res.send('Invalid username or password');
return
}
rows.forEach( async (row) => {
if (row.regname === req.body.regname && await bcrypt.compare(req.body.regpassword, row.regpassword) ) {
x = 1;
}
else {
x = 2;
db.close();
}
})
if (x === 1) {
res.json({
"answer":"Success",
})
}
else {
res.json(
{"answer":"Denied",
})
}
})
})
salt
也需要存储在数据库中。
然后 /login
路由必须根据 req.body.regname
从数据库中检索 regpassword
和 salt
。然后它需要 运行 一个 await bcrypt.hash(req.body.regpassword, salt)
与 /register
路由完全相同,然后将该哈希操作的结果与数据库中的 regpassword
进行比较。如果两个哈希值匹配,则用户提供了正确的密码,您可以显示一些确认信息/发出一些会话令牌/ ...
我在这里分享我的解决方案,如果有人需要的话:
router.post('/login', (req, res) => {
const regname = req.body.regname;
const regpassword = req.body.regpassword;
const findUserByName = (regname, cb) => {
return db.get(`SELECT * FROM Users WHERE regname = ?`,[regname], (err, row) => {
cb(err, row)
});
}
findUserByName(regname, (err, user)=>{
if (err) return res.status(500).send('Server error!');
if (!user) return res.status(404).send('User not found!');
const result = bcrypt.compareSync(regpassword, user.regpassword);
if(!result) return res.status(401).send('Password not valid!');
res.status(200)
res.json({
"answer":"Success",
})
});
});
我目前正在构建一个带有 Nodejs/Express 后端的 React 应用程序,并尝试实现登录身份验证。
我用姓名、电子邮件、密码注册用户,并用 bcrypt 散列密码:
router.post('/register', async (req, res) => {
// Hashing
const salt = await bcrypt.genSalt(10)
const hashedPassword = await bcrypt.hash(req.body.regpassword, salt)
// Validate
const {error} = Joi.validate(req.body, schema)
var data = {
regname: req.body.regname,
regemail: req.body.regemail,
regpassword : hashedPassword
}
var sql ='INSERT INTO Users (regname, regemail, regpassword) VALUES (?,?,?)'
var params =[data.regname, data.regemail, data.regpassword]
db.run(sql, params, function (err, result) {
if (error){
res.status(400).send(error.details[0].message);
return;
}
res.json({
"answer": "Success",
})
res.status(200)
});
})
这很好用。但是我的 /login 路由不起作用:
router.post('/login', (req, res, next) => {
let sql = `SELECT * FROM Users WHERE regname = "${req.body.regname}" AND regpassword = "${req.body.regpassword}"`;
var x;
db.all(sql, (err, rows) => {
if (err) {
next(err);
return;
}
if (!rows) {
res.status(400);
res.send('Invalid username or password');
return
}
rows.forEach( async (row) => {
if (row.regname === req.body.regname && await bcrypt.compare(req.body.regpassword, row.regpassword) ) {
x = 1;
}
else {
x = 2;
db.close();
}
})
if (x === 1) {
res.json({
"answer":"Success",
})
}
else {
res.json(
{"answer":"Denied",
})
}
})
})
salt
也需要存储在数据库中。
然后 /login
路由必须根据 req.body.regname
从数据库中检索 regpassword
和 salt
。然后它需要 运行 一个 await bcrypt.hash(req.body.regpassword, salt)
与 /register
路由完全相同,然后将该哈希操作的结果与数据库中的 regpassword
进行比较。如果两个哈希值匹配,则用户提供了正确的密码,您可以显示一些确认信息/发出一些会话令牌/ ...
我在这里分享我的解决方案,如果有人需要的话:
router.post('/login', (req, res) => {
const regname = req.body.regname;
const regpassword = req.body.regpassword;
const findUserByName = (regname, cb) => {
return db.get(`SELECT * FROM Users WHERE regname = ?`,[regname], (err, row) => {
cb(err, row)
});
}
findUserByName(regname, (err, user)=>{
if (err) return res.status(500).send('Server error!');
if (!user) return res.status(404).send('User not found!');
const result = bcrypt.compareSync(regpassword, user.regpassword);
if(!result) return res.status(401).send('Password not valid!');
res.status(200)
res.json({
"answer":"Success",
})
});
});