javascript - 将值从内部函数传递到外部函数 - 无法保存密码

标签 javascript asynchronous scope callback

我尝试使用 crypto 散列密码,但我无法将它们保存在数据库中。

我有 node.js 4.2.3 express 4.13.3,我的数据库是 PostgreSQL 9.1。该字段是 character varying (255) 并命名为 pswrd

这是我的代码:

var tobi = new User({
    usrnm:'sp',
    pswrd:'an'
});

module.exports = User;

function User(obj){
    for(var key in obj){
        this[key] = obj[key];
    }
}

User.prototype.save = function (fn){
    var user=this;
     //EDIT, added this :
     var psw ;
    var salt = crypto.randomBytes(50).toString('base64');
    crypto.pbkdf2(user.pswrd, salt, 10000, 150, 'sha512',function(err, derivedKey) {
        //user.pswrd = derivedKey.toString('hex');
         //EDIT, added this:
         var justCrypted = derivedKey.toString('hex');
    });

    var query=client.query('INSERT INTO mytable(usrnm,pswrd)VALUES($1,$2) RETURNING mytable_id',[user.usrnm,user.pswrd], function(err, result) {
        if(err) {console.log(err)}
        else {
          var newlyCreatedId = result.rows[0].mytable_id;
        }
    });
    query.on("end", function (result) {console.log(result);client.end();});
}

tobi.save(function (err){
    if (err)throw error;
    console.log("yo");
})  

要运行它,我输入 node lib/user。我没有收到任何错误,但密码未正确保存。第一个值被保存,an,而不是散列值。我在这里缺少什么?

编辑

AshleyB 的回答很好,但是,请帮助我理解如何将数据从内部函数 (crypto.pbkdf2) 传递到其外部函数 (User.prototype.save = function (fn )) ,当内部已经预定义,固定语法 (crypto.pbkdf2) ,所以我不知道是否或如何编辑它。

我怎样才能保持代码不变并仍然将 justCrypted 传递回 psw(请参阅代码编辑)?如果它是我编写的函数,我想我可以使用 apply,但是,crypto.pbkdf2 是预定义的,我不知道是否可以向它添加东西。

谢谢

最佳答案

问题出在范围上,当前查询更改后的 user.pswrd 超出了查询范围,因此它回落到顶部分配的值。

通过将查询移动到 'crypto.pbkdf2'... block 中,user.pswrd 值将按预期工作。我已经更新了您的代码(并使 salt 生成异步,因为您已经使用了 pbkdf2 的异步版本)。

var tobi = new User({
  usrnm: 'sp',
  pswrd: 'an'
});

module.exports = User;

function User(obj) {
  for (var key in obj) {
    this[key] = obj[key];
  }
}

User.prototype.save = function(fn) {
  var user = this;


  // Changed salt generation to async version
  // See: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback

  crypto.randomBytes(50, function(ex, buf) {
  if (ex) throw ex;
  salt = buf.toString('base64');

    // password, salt, iterations, keylen[, digest], callback
    crypto.pbkdf2(user.pswrd, salt, 10000, 150, 'sha512', function(err, derivedKey) {
    user.pswrd = derivedKey.toString('hex');

        // Moved the query within the hash function
    var query = client.query('INSERT INTO mytable(usrnm,pswrd)VALUES($1,$2) RETURNING mytable_id', [user.usrnm, user.pswrd], function(err, result) {
      if (err) {
        console.log(err)
      } else {
        var newlyCreatedId = result.rows[0].mytable_id;
      }
    });
    query.on("end", function(result) {
      console.log(result);
      client.end();
    });

  });


    });

}


tobi.save(function(err) {
  if (err) throw error;
  console.log("yo");
})

关于javascript - 将值从内部函数传递到外部函数 - 无法保存密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34458576/

相关文章:

javascript - 使用javascript的mongodb shell中的变量集合名称

events - 在多线程代码中使用 F# 事件和异步事件

C# 等待 TcpClient ConnectAsync/ReadToEndAsync 超时

c# - 基于异步/等待的 Windows 服务中的同步 I/O

c - 为什么我需要在外部声明这个函数。没有它也能工作

在文件中搜索一定范围内的文本? (升华)

javascript - 如何在选择及其父 div 及其邻居按钮上切换禁用

javascript - 嵌入网络浏览器时,Javascript 是 DOM 交互的唯一选择吗?

javascript - 无法在 JS 中设置 null 的属性 'innerHTML'

JavaScript + jQuery 这个范围