【问题标题】:Cannot set headers after they are sent to the client - Node/Express/JWT将标头发送到客户端后无法设置标头 - Node/Express/JWT
【发布时间】:2020-10-15 18:59:21
【问题描述】:

我目前正在编写使用 JWT 进行身份验证的“模块化”REST API。这是一个压力很大的过程,但我一直在遇到问题并一一解决。遗憾的是,我偶然发现了一个我不确定如何解决的问题。

基本上,我有一个身份验证端点,我在其中使用新的用户信息发出 POST 请求,但由于某种原因,我不断收到错误消息“未处理的拒绝错误 [ERR_HTTP_HEADERS_SENT]:发送到客户端后无法设置标头”

此端点的工作方式是它调用一个名为 createUser 的控制器函数,如下所示:

'use strict'

const UserService = require('../../services/users')
const User = require('../../domain/user')
const TokenService = require('../../services/tokens')

const config = require("../../config/auth.config"); //secret key

const tokenService = new TokenService()
const userService = new UserService()
const mailService = require('../../services/mail')

class UserController {
  createUser(req, res, next) {
    console.log("Create user!")
    console.log("User: " + JSON.stringify(req.body));
    const user = new User(req.body)

    userService.createNewUser(user).then(user => {
      return tokenService.createToken({
        firstName: user.firstName,
        lastName: user.lastName,
        email: user.email,
      }, config.secret)
    }).then(token => {
      // who cares if it fails, we have a resend option
      return mailService.sendActivationEmail(user.email, token)
    }).then(() => {
      res.status(201).send()
    }).catch(err => res.status(500).send(err.message))
    next();
  }

  activateUser(req, res, next) {
    const token = req.query.token
    tokenService.verifyToken(token, config.secret).then(user => {
      if (!user || !user.email) {
        throw new Error('Token not valid')
      }
      return userService.activateUser(user.email)
    }).then(() => {
      res.status(202).send({apiToken: token})
    }).catch(err => {
      res.status(500).send(err.message)
    })
  }
}

module.exports = UserController;

然后它调用我创建的用户服务,然后调用处理令牌创建、验证等的令牌服务。通过一堆日志记录语句,我将问题缩小到包含 createToken 函数的 TokenService,如下所示:

'use strict'

const jwt = require('jsonwebtoken')

module.exports = (embeddedData, secretKey) => {
  console.log('Embedded Data:' + JSON.stringify(embeddedData))
  return Promise.resolve(jwt.sign(embeddedData, secretKey))
  console.log("Token created.");
}

在输出 JSON 的嵌入式数据输出之后:{"firstName":"John","lastName":"Smith","email":"johnsmith123@gmail.com"}

“发送到客户端后无法设置标头”发生在那里,因此“创建的令牌”没有输出

我已经搜索过 StackOverflow,但从我所看到的情况来看,我认为我做的一切都是正确的。如果有帮助,我将我的路线定义为:

  app.post("/api/auth/signup",
    controller.createUser
  );

我会很感激任何帮助,我一直在为此摸不着头脑,不知道下一步该怎么做。

谢谢!

【问题讨论】:

  • 一般来说,当一段代码已经发送响应并且您的程序遇到另一段发送另一个响应的代码时,就会发生此异常。由于 http 只能发送一个,并且只有一个响应。
  • 您正在发送响应并再次调用下一个中间件。下一个()。
  • @MohanKrishnaSai 哇,我忘了我把 next() 放在那里,之前正在测试一些东西,忘记删除它来看看它是如何工作的。这就是问题所在……哎呀????

标签: node.js express promise jwt


【解决方案1】:

您正在发送响应并再次调用下一个中间件。下一个()。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    • 1970-01-01
    • 2021-03-05
    • 2020-11-14
    • 2020-11-02
    • 2021-06-18
    相关资源
    最近更新 更多