【问题标题】:Error: Can't set headers after they are sent when return jwt.verify错误:返回 jwt.verify 时发送后无法设置标头
【发布时间】:2020-04-18 21:08:21
【问题描述】:

我想根据控制器的功能进行身份验证,所以我创建了isAuthorized 函数,如下所示:

const isAuthorized = (req) => {
  const token = req.cookies['jwt'];
  const sign = process.env.JWT_SECRET_KEY;

  return jwt.verify(token, sign, function(err, decoded) {
    console.log(decoded);
    if (err || !decoded) {
      console.log('invalid token');
      return false;
    } else if (decoded && (!decoded.access || decoded.access == 'unauthenticated')) {
      console.log('unauthenticated token');
      return false;
    } else if (decoded && decoded.access == 'authenticated') {
      console.log('valid token');
      return true;
    } else {
      console.log('something suspicious');
      return false;
    }
  });
};

用法:

const viewLogin = (req, res, next) => {
  if (isAuthorized(req)) {
    res.send('Already Logged In');
  }
  res.render('login');
};

它完全符合我的要求,但我在终端上出现错误。

GET /auth/login 200 8.810 ms - 17
Error: Can't set headers after they are sent.
    at SendStream.headersAlreadySent (/Users/james/Documents/Workspace/Centell/Project/weaver/node_modules/send/index.js:390:13)
    at SendStream.send (/Users/james/Documents/Workspace/Centell/Project/weaver/node_modules/send/index.js:618:10)
    at onstat (/Users/james/Documents/Workspace/Centell/Project/weaver/node_modules/send/index.js:730:10)
    at FSReqCallback.oncomplete (fs.js:159:5)

我尝试过:

  • 从外部定义令牌(viewLogin)并将其作为参数发送(isAuthrized(token))。
  • 使用异步/等待模式。 (await usAuthrized(req))
  • isAuthorized中分隔结果变量。
const isAuthorized = req => {
  const token = req.cookies['jwt'];
  const sign = process.env.JWT_SECRET_KEY;
  let result;

  return jwt.verify(token, sign, function(err, decoded) {
    console.log(decoded);
    if (err || !decoded) {
      console.log('invalid token');
      result = false;
    } else if (decoded && (!decoded.access || decoded.access == 'unauthenticated')) {
      console.log('unauthenticated token');
      result = false;
    } else if (decoded && decoded.access == 'authenticated') {
      console.log('valid token');
      result = true;
    } else {
      console.log('something suspicious');
      result = false;
    }
  });

  return result;
};


但这些都行不通。

如何解决这个错误?

【问题讨论】:

    标签: javascript node.js express jwt


    【解决方案1】:

    修改代码如下:

    const viewLogin = (req, res, next) => {
      if (isAuthorized(req)) {
        res.send('Already Logged In');
      } else {
        res.render('login');
      }
    };
    

    const viewLogin = (req, res, next) => {
      if (isAuthorized(req)) {
        return res.send('Already Logged In');
      }
      res.render('login');
    };
    

    【讨论】:

    • 谢谢!有用!但我不明白发生了什么。你能解释一下它为什么起作用吗??
    【解决方案2】:

    解释为什么原件不起作用。由于已经使用 res.send 发送了响应,因此您将无法同时使用 res.render。为了防止 res.render 执行,您需要返回 res.send 或使用 if/else 语句,如另一个答案所示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-08
      • 2018-06-29
      • 2013-12-22
      • 1970-01-01
      • 1970-01-01
      • 2017-12-22
      相关资源
      最近更新 更多