还记得第2天在做专案规划时,有提到一个目标「加密敏感资料实现资安管理」吗?
目前我们的密码还是一样放在资料库上全裸
今天进度目标要来将密码加密存放,并实作比对密码
另外会多写一个重置密码的功能,让系统将密码重设
我们会用到 bcryptjs 此套件来做密码加密等动作,此套件的加密是不可逆的,所以没有办法从加密後的结果回推原始密码,相对安全性提高非常多
开启後端(b2e)专案,我们来安装它吧~
输入安装指令:
npm install bcryptjs
接着就等安装完罗~安装成功後会有这些讯息:
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
+ [email protected]
added 1 package from 6 contributors and audited 250 packages in 3.382s
10 packages are looking for funding
run `npm fund` for details
found 4 vulnerabilities (3 low, 1 critical)
run `npm audit fix` to fix them, or `npm audit` for details
╭────────────────────────────────────────────────────────────────╮
│ │
│ New patch version of npm available! 6.14.4 -> 6.14.8 │
│ Changelog: https://github.com/npm/cli/releases/tag/v6.14.8 │
│ Run npm install -g npm to update! │
│ │
╰────────────────────────────────────────────────────────────────╯
开启 /modules/user.module.js 引用套件:
const bcrypt = require('bcryptjs');
安装的部份就完成罗!!
接着要做一个API将原来的密码重设为加密後的密码~
可以将这个API的用途想像成Google的密码重设功能!!
开启 /routes/users/index.js 新增路由:
router.post('/resetpswd', userCtrl.userCtrlResetPswd);
开启 /controllers/users.controller.js 加上 userCtrlResetPswd,将要修改密码的帐号及新的密码传入module处理:
const userCtrlResetPswd = (req, res) => {
userModule.userModuleResetPswd({
accountId: req.body.accountId,
newPassword: req.body.newPassword,
}).then((moduleResult) => {
res.send(Object.assign({ success: true }, moduleResult));
}).catch((error) => {
res.send(Object.assign({ success: false }, error));
});
};
module.exports = {
...,
userCtrlResetPswd,
}
开启 /modules/users.module.js 加上 userModuleResetPswd,前面的连线可以直接大绝招xD
const userModuleResetPswd = (values) => {
return new Promise((resolve, reject) => {
MongoClient.connect(mongoDBConnectionUrl, {
useUnifiedTopology: true
}).then((client) => {
client.db(`${config.mongodb.DATABASE}`).collection("users", (error, collection) => {
if (error) {
reject({ message: error });
} else {
...
}
});
}).catch(error => {
reject({ message: error });
});
});
};
连线成功後,会用到 findOneAndUpdate()
方法,找到对应的帐号资料後将该笔资料做密码更新:
collection.findOneAndUpdate(
{ accountId: values.accountId },
{ $set: { password: bcrypt.hashSync(values.newPassword, 10) } }
).then((result) => {
if (result.value === null) {
reject({ message: '无法重设密码' });
} else {
resolve({ message: '重设完成' });
}
}).catch((error) => {
reject({ message: error });
}).finally(() => {
client.close();
});
重点在第3行: bcrypt.hashSync(values.newPassword, 10)
用到了 bcrypt 套件的 hashSync('加密值', 加盐次数)
方法
到这边就完成重置密码罗!!
来用POSTMAN看一下结果吧~
从Compass可以看到密码已经重置成看似乱码的资料了!!
最後在登入验证的部分需要改为 bcrypt套件的验证方式
开启 /modules/users.module.js 来到 userModuleSignin 方法
将原来验证密码的方式改为 bcrypt 的验证方法 compare(要比对的密码, 资料库的密码)
:
bcrypt.compare(values.password, user.password).then((result) => {
if (result) {
//验证成功
} else {
//验证失败
}
});
根据比对结果判断验证是成功或失败
把原本的成功或失败的内容移进去:
collection.findOne({ accountId: values.accountId }).then((user) => {
if (user) {
bcrypt.compare(values.password, user.password).then((result) => {
if (result) {
const payload = {
accountId: user.accountId,
username: user.username,
exp: Math.floor(Date.now() / 1000) + config.jwt.exp
};
const token = jwt.sign(payload, config.jwt.tokensecret);
resolve({ message: '登入成功', token });
} else {
reject({ message: '密码错误' });
}
});
} else {
reject({ message: '无此帐号' });
}
client.close();
});
这样就达成目标「加密敏感资料实现资安管理」罗!!
今日重点:
.hashSync()
方法做加密.compare()
方法做加密资料比对有需要改进或是任何意见建议欢迎下面留言~
<<: 拥抱「资料结构」的「演算法」(29) - 戴克斯特拉演算法求最短路径
我家使用的是大大宽频 没有固定ip 最近购入一台totolink的路由器想要架设vpn 但是设定完了...
语言除了能够传达字面上的讯息之外,也蕴含了说话者所要表达的情绪,情绪的展现能够让对方更清楚的了解讯息...
记忆犹深的痞客帮铁人赛第一天, 由於首次加入铁人赛的行列, 因此开了一篇不在铁人赛内的文章, 当天发...
javap介绍 javap是jdk工具中自带的反编译工具,它是根据class位元组码档案,反解析出当...
前几天有练习了小蜘蛛和跳过鱼 今天还是持续练习Web的工具 透过这些工具可以辅助我们更顺利进行手动测...