RESTAPI-在JSON响应中获取密码安全吗

RESTAPI-在JSON响应中获取密码安全吗,json,node.js,rest,Json,Node.js,Rest,我正在使用Node.js和JWTs编写RESTAPI 我有下面的路径来验证用户 我想问一下,从方法user.findOne返回的user返回了正确的密码,因此我可以检查它是否正确。 但是这样做安全吗?我做了一个console.log,它显示了密码(尽管是加密的),但仍然感觉不安全,因为有人肯定会看到 router.post('/authenticate', function(req, res) { // find the user User.findOne({ name: re

我正在使用Node.js和JWTs编写RESTAPI

我有下面的路径来验证用户

我想问一下,从方法
user.findOne
返回的
user
返回了正确的密码,因此我可以检查它是否正确。 但是这样做安全吗?我做了一个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
        });
      }

    }

  });
});
没有

此外,密码不应该加密保存在数据库中,而是散列保存。经典环境将密码保存为例如md5(更常见)或bcrypt(更安全)散列

这确保了即使你的数据库被盗,也没有人会拥有你用户的密码;没有办法“解密”散列(不是在一亿年内)

当用户登录时,将输入密码的哈希值与分配给该用户的哈希值进行比较。您可以使用诸如

编辑

从技术角度来看,这并不危险。启动服务器时,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为每个哈希操作使用随机盐。这意味着,无论何时对给定的输入进行散列,每次都会产生不同的散列。然后将盐存储为哈希的一部分,然后可以对哈希进行验证。请查看更多信息。

否。此外,将密码存储在服务器上不安全。您应该使用安全的哈希机制在服务器上进行身份验证,这样就不会存储原始密码。关于这个主题,这里有一些很好的信息:这里:我们在当前的项目中正在做类似的事情,到目前为止,我们没有任何问题。对我们来说,生成的JWT令牌仍保留在浏览器缓存中。还有一点需要补充的是,我们的应用程序是组织内部的。问题不是你以某种方式传递密码,问题是你需要在某个地方未加密才能传递密码。这通常已经不是个好主意了。@userMod2:请查看我的最新编辑。我添加了一些您可能最感兴趣的技术方面。如果我的答案令人满意,也要确保投票并接受。谢谢-所以哈希位是有意义的。然而,流动会是什么。用户输入用户名+密码。然后我是否发送用户名+散列密码,并在发送真或假密码之前在服务器上检查它是否匹配?如果是这样的话,那么通过https发送散列密码怎么样?有两种选择:要么在客户端对密码进行散列并直接比较,要么只有在使用https的情况下才发送普通密码并在服务器上进行散列。如果有人截获流量并获取哈希,此人也可以重播哈希以获得访问权。因此,最好使用HTTPS,不要关心其他内容;)要记住的另一件事是,对用户是否不存在或密码是否错误做出不同的响应不是一个好主意。如果这样做,在找到正确的用户名之前枚举用户是很简单的。如果您以相同的方式响应(
401 Unauthorized
),攻击者就不知道哪个是错误的。因此,如果找不到用户,您可能希望与占位符密码进行比较,因此服务请求所花费的时间也是相同的。关于您的建议,我再次编辑了代码,并添加了您提到的安全要求。还有什么问题吗?=)是的,有了你的指导,所有的一切都很好。我对认证安全性的关键概念有了很好的整体认识。再次感谢你的帮助。