我正在使用Node.js编写Rest API并使用JWT。
我有以下路线来验证用户身份。
我想问一下,从方法user
返回的User.findOne
会返回正确的密码,因此我可以检查它是否正确。
但这样做安全吗?我做了一个console.log,它显示了密码(虽然是加密的),但仍然感觉不安全,因为有人肯定可以查看?
router.post('/authenticate', function(req, res) {
// find the user
User.findOne({
name: req.body.name
}, function(err, user) {
if (err) throw err;
if (!user) {
res.json({ success: false, message: 'Authentication failed. User not found.' });
} else if (user) {
// check if password matches
if (user.password != req.body.password) {
res.json({ success: false, message: 'Authentication failed. Wrong password.' });
} else {
// if user is found and password is right
// create a token
var token = jwt.sign(user, app.get('superSecret'), {
expiresInMinutes: 1440 // expires in 24 hours
});
// return the information including token as JSON
res.json({
success: true,
message: 'Enjoy your token!',
token: token
});
}
}
});
});
答案 0 :(得分:2)
没有
此外,密码不应保存在数据库中加密,而是哈希。经典环境保存密码,例如md5(更常见)或bcrypt(更安全)散列。
这确保即使您的数据库被盗,也没有人会拥有您的用户的密码;没有办法“解密”哈希(不是一亿年)。
当用户登录时,您将输入的密码的哈希值与分配给用户的哈希值进行比较。您可以使用像bcrypt-nodejs
这样的优秀模块修改强>
从技术方面来说,它并不危险。当您启动服务器时,JavaScript会编译您的代码并在V8引擎中执行结果。只要保存节点和MySQL之间的连接,就无法访问数据库返回的内容。 有人可能会转储服务器内存并希望找到合适的位。但如果有人获得了必要的许可,你就会注定失败。
我为你实现了一个例子,它没有经过测试,但应该告诉你它是什么意思。
router.post('/register', function(req, res) {
bcrypt.hash(req.body.password, null, null, function(err, hash) {
if (!err) {
var newUser = new User({
name: req.body.name,
password: hash
});
newUser.save(); // ????
}
});
});
router.post('/authenticate', function(req, res) {
User.findOne({
name: req.body.name
}, function(err, user) {
var password = 'GP%Z!zvbk/9>Ss-R';
var passwordHash = '$2a$10$W.zZPCaNOuR152I4qENKH.8h7I6BPcfCYBJqHPNXbVaBz0XWVxnBm'; // bcrypt of string ')RZK&M(QX"k188cw'
if (user) {
password = req.body.password;
passwordHash = user.password;
}
bcrypt.compare(password, passwordHash, function(err, success) {
if (success) {
var token = jwt.sign(user, app.get('superSecret'), {
expiresInMinutes: 1440
});
res.json({
success: true,
message: 'Enjoy your token!',
token: token
});
}
else {
res.status(401).json({
success: false,
message: 'Authentication failed.'
});
}
});
});
});
注意:对于每个哈希操作,bcrypt默认使用随机盐。这意味着,无论何时散列给定输入,它每次都会产生不同的散列。然后将盐存储为哈希的一部分,然后可以对其进行验证。请查看Wikipedia以获取更多信息。