如何解决Node.js Express和Axios场景下自签名证书报错问题
故障根因定位
首先要明确:你遇到的DEPTH_ZERO_SELF_SIGNED_CERT错误是NodeJS作为客户端请求目标服务器时,目标返回的证书是自签名证书,不在Node的默认信任根证书列表中,和你自己服务器上Nginx的Let's Encrypt证书完全无关,你重新签发自有证书的操作无法解决该问题。
你之前的方案不生效,基本是环境变量未正确注入进程、或者axios版本bug导致的。
排查步骤
- 先确认问题归属:在Ubuntu服务器本地执行curl命令请求目标地址
curl -v $WEBHOOK_URL
如果curl也报证书错误,说明是目标服务器的证书问题,和你的代码逻辑无关;如果curl请求正常,再排查Node服务的配置问题。
可行解决方案
方案1:修复环境变量/Agent配置不生效问题
- 如果你用PM2、systemd等进程管理工具运行Node服务,直接在当前shell执行
export NODE_TLS_REJECT_UNAUTHORIZED='0'不会作用到已有进程:- PM2:执行
pm2 set env NODE_TLS_REJECT_UNAUTHORIZED=0,然后pm2 restart 你的进程名即可 - systemd:在对应.service文件的
[Service]块添加Environment="NODE_TLS_REJECT_UNAUTHORIZED=0",然后执行systemctl daemon-reload && systemctl restart 你的服务名
- PM2:执行
- 如果你是用httpsAgent的方案,部分旧版本axios存在Agent配置不生效的bug,你可以直接在axios的请求config中添加
rejectUnauthorized: false参数,或者将axios升级到1.x以上稳定版。
方案2:更安全的证书信任方案(推荐)
直接关闭证书校验存在安全风险,你可以手动将目标服务器的自签名证书加入信任列表:
- 导出目标服务器的证书:
openssl s_client -connect 目标域名:443 -showcerts < /dev/null | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > target-cert.pem
- 修改你的httpsAgent配置:
const TARGET_CERT = fs.readFileSync('./path/to/target-cert.pem') const httpsAgent = new https.Agent({ ca: TARGET_CERT })
该方案既解决了证书不被信任的问题,也保留了TLS的安全校验能力。
额外说明
你代码中注释掉的cert、key参数是客户端双向校验时才需要的配置,如果目标服务器没有要求你上传客户端证书,不需要配置这两个参数。
内容的提问来源于stack exchange,提问作者intercoder
相关产品推荐
相关产品推荐

