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

Node.js Express如何获取真实源主机名以防止伪造?

解决Express中获取真实源主机名的问题

核心问题原因

req.hostname直接读取HTTP请求头的Host字段,客户端可随意篡改该字段,因此无法直接用它获取真实主机名。针对多域名场景,推荐以下几种可靠方案:


方案1:通过反向代理传递真实主机信息

若应用部署在Nginx、Apache等反向代理后,这是最稳妥的方案:

  1. 配置反向代理,将原始请求的真实主机名通过自定义请求头传递给Express:
    以Nginx为例,添加配置:
    proxy_set_header X-Real-Host $host;
    proxy_set_header X-Forwarded-Host $host;
    
  2. 在Express中开启信任代理配置,确保能正确读取代理传递的头信息:
    app.set('trust proxy', true);
    // 也可指定信任的代理IP范围,比如仅信任本地代理:app.set('trust proxy', ['127.0.0.1'])
    
  3. 之后通过req.get('X-Real-Host')或req.get('X-Forwarded-Host')即可获取真实主机名——代理层会传递原始请求的真实Host,客户端篡改的Host会被代理忽略。

方案2:端口-域名映射(无代理场景)

若应用直接暴露在公网,且每个域名绑定独立端口,可在应用内部维护端口与域名的映射表:

// 预先配置域名与端口的对应关系
const domainPortMap = {
  'example.com': 3000,
  'foo.com': 3001,
  'bar.com': 3002
};

app.use((req, res, next) => {
  // 通过当前请求的本地端口反向查找对应域名
  const realHostname = Object.keys(domainPortMap).find(domain => domainPortMap[domain] === req.socket.localPort);
  req.realHostname = realHostname;
  next();
});

该方案的前提是每个域名对应唯一端口,客户端无法修改请求的目标端口(除非直接访问其他端口,对应不同域名),因此能保证获取到真实主机名。

方案3:HTTPS证书验证(加密场景)

若应用启用了HTTPS,可利用TLS握手阶段的证书信息确认真实域名:

app.use((req, res, next) => {
  if (req.socket.encrypted) {
    // 获取当前连接的服务器证书
    const serverCert = req.socket.getPeerCertificate(true);
    // 从证书的CN字段提取真实域名(前提是每个域名对应独立SSL证书)
    const realHostname = serverCert.subject.CN;
    req.realHostname = realHostname;
  }
  next();
});

客户端无法篡改TLS握手时使用的证书,因此该方式能确保获取到的域名是真实绑定的证书域名,安全性最高。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 06:42:52