【问题标题】:Headers have already been sent - Koa and bcrypt标头已经发送 - Koa 和 bcrypt
【发布时间】:2018-02-27 22:44:18
【问题描述】:

我正在尝试为我的应用创建登录端点。创建用户时,我使用 bcrypt 对密码进行哈希处理。登录时,我想将哈希与字符串密码进行比较。但是,当我使用邮递员登录时,我收到 404 错误“标头已发送”。我查看了 koa git 论坛using crypto with koa 2 并且接受的答案建议将函数包装在异步等待中,这就是我所做的。我不明白为什么节点不断向我发送“标头已发送”错误。

var User = db.get('users');
var Review = db.get('reviews');

//this create user function works as intended...

module.exports.create = async (ctx, next) => {
  if ('POST' != ctx.method) return await next();

  let user = ctx.request.body;

  console.log('CREATE USER params:');
  console.log(user);

  console.log(user.username);
  let users = await User.find({username:user.username});
  console.log(users); //why is this a function???
  if (users.length > 0) {
    ctx.status = 400;
    ctx.body = {
      errors:[
        'Username already exists.'
      ]
    };
  } else {
    const hash = await bcrypt.hash(user.password, 10);
    await User.insert({username:user.username, password:hash});
    console.log('Creating user…');
    console.log(user);
    ctx.body = filterProps(user, ['username']);
    ctx.status = 201;
    }
  };

module.exports.signIn = async (ctx, next) => {

  const encoded = ctx.request.headers.authorization.split(' ')[1];
  const decoded = base64url.decode(encoded);
  const [username, password] = decoded.split(':');
  const user = await User.findOne({username:username});
 
  //problematic code here...

  await bcrypt.compare(password, user.password, function (err, res) {
    if (res) {
      ctx.status = 200;
      ctx.body = 'success';
    } else {
      ctx.status = 401;
      ctx.body = {
        errors:['password incorrect for this username']
      }
    }
  });
}

【问题讨论】:

  • 这是全部代码吗?有什么东西触发了这个功能吗?您的错误通常意味着您已向客户发送了响应,而您正在发送另一个您无法执行的响应。您通常只能在您的场景中响应一次。
  • 像往常一样,当你已经发送了一些东西到输出时,你会看到这个问题。有时,当我们的依赖项之一出现错误时会发生这种情况。此外,问题可能是由另一个中间件引起的。内容可能已经发送到那里。

标签: javascript bcrypt koa


【解决方案1】:

所以问题在于我如何使用 bcrypt compare。我将结果存储在变量中而不是使用回调并且它有效。为什么,我不知道...

module.exports.signIn = async (ctx, next) => {
  const encoded = ctx.request.headers.authorization.split(' ')[1];
  const decoded = base64url.decode(encoded);
  const [username, password] = decoded.split(':');
  const user = await User.findOne({username:username});
  
  const correct = await bcrypt.compare(password, user.password)
  if (correct) {
    ctx.status = 200;
    ctx.body = 'success';
  }
  else {
    ctx.status = 401;
    ctx.body = {
      errors:['wrong credentials']
    }
  }
};

【讨论】:

  • 如果你传递一个回调,bcrypt.compare 返回undefined 而不是一个promise,所以await 最终不会等待任何东西。然后当回调发生时,响应已经完成......不幸的是await undefined在JavaScript中是有效的=/
猜你喜欢
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-17
  • 1970-01-01
相关资源
最近更新 更多