You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ExpressJS登录鉴权密码验证报错及连接拒绝问题求助

问题描述

我用ExpressJS开发登录鉴权接口,输入错误用户名或密码时,Postman能收到响应,但终端抛出ERR_HTTP_HEADERS_SENT错误;第二次发起请求时,Postman返回“Error: connect ECONNREFUSED 127.0.0.1:5000”。附上代码和错误日志,求解决。

代码

const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");

//REGISTER

router.post("/register", async (req, res) => {
  try {
    const salt = await bcrypt.genSalt(10);
    const hashedPass = await bcrypt.hash(req.body.password, salt);
    const newUser = new User({
      username: req.body.username,
      email: req.body.email,
      password: hashedPass,
    });
    const user = await newUser.save();
    res.status(200).json(user);
  } catch (err) {
    res.status(500).json(err);
  }
});

//LOGIN

router.post("/login", async (req, res) => {
  try {
    const user = await User.findOne({ username: req.body.username });
    !user && res.status(400).json("Wrong credentials");

    const validate = await bcrypt.compare(req.body.password, user.password);
    !validate && res.status(400).json("Wrong credentials");

    res.status(200).json(user);
  } catch (err) {
    res.status(500).json(err);
  }
});

module.exports = router;

错误日志

node:internal/errors:465
ErrorCaptureStackTrace(err);
^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (node:internal/errors:372:5)
    at ServerResponse.setHeader (node:_http_outgoing:576:11)
    at ServerResponse.header (C:\Users\Rahmad Hidayat\Desktop\react-blog\api\node_modules\express\lib\response.js:794:10)
    at ServerResponse.send (C:\Users\Rahmad Hidayat\Desktop\react-blog\api\node_modules\express\lib\response.js:174:12)
    at ServerResponse.json (C:\Users\Rahmad Hidayat\Desktop\react-blog\api\node_modules\express\lib\response.js:278:15)
    at C:\Users\Rahmad Hidayat\Desktop\react-blog\api\routes\auth.js:35:21 {
  code: 'ERR_HTTP_HEADERS_SENT'
}
[nodemon] app crashed - waiting for file changes before starting...
解决方案

1. 问题根源

ERR_HTTP_HEADERS_SENT错误是因为单次请求中发送了多次响应。登录接口里,当用户不存在时,代码执行!user && res.status(400).json("Wrong credentials")发送了一次响应,但没有终止后续代码,继续执行到const validate = await bcrypt.compare(...)时,user为undefined,访问user.password会抛出错误,进入catch块再次发送500响应,导致重复设置响应头。

而第二次请求的ECONNREFUSED是因为错误导致Node进程崩溃,nodemon重启前服务器未运行,所以连接被拒绝。

2. 修复后的登录接口代码

router.post("/login", async (req, res) => {
  try {
    const user = await User.findOne({ username: req.body.username });
    if (!user) {
      return res.status(400).json("Wrong credentials");
    }

    const validate = await bcrypt.compare(req.body.password, user.password);
    if (!validate) {
      return res.status(400).json("Wrong credentials");
    }

    res.status(200).json(user);
  } catch (err) {
    res.status(500).json(err);
  }
});

3. 修复说明

  • 使用if (!user) { return res.send(...) }:当用户不存在时,发送响应后立即return终止后续代码执行,避免访问undefined的user.password引发错误,同时确保只发送一次响应。
  • 密码验证失败时同样用return终止流程,严格保证每个请求仅发送一次响应。

修改后不会再出现重复设置响应头的错误,Node进程也不会崩溃,后续请求能正常连接服务器。

内容的提问来源于stack exchange,提问作者Rahmat Hidayat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 12:43:01