自签名证书遭客户端拒绝,Node.js HTTPS服务问题怎么解决?
问题描述
后端搭建了基于Node.js + Express的HTTPS服务器,仅包含一个用于打印日志的测试接口/test。生成证书和密钥使用的OpenSSL配置文件req.cnf内容如下:
[req] distinguished_name = req_distinguished_name x509_extensions = v3_req prompt = no [req_distinguished_name] CN = www.localhost.com [v3_req] keyUsage = critical, digitalSignature, keyAgreement extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = www.localhost.com DNS.2 = localhost.com DNS.3 = localhost
在配置文件同目录下执行以下命令生成证书:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout cert.key -out cert.pem -config req.cnf -sha256
前端通过Vue按钮调用/test接口时,出现以下错误:
- Firefox:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:3001/test. (Reason: CORS request did not succeed). Status code: (null). - Chrome:
GET https://localhost:3001/test net::ERR_CERT_AUTHORITY_INVALID
补充信息:
- 使用本地网络IP替代
localhost时,错误相同; - 服务器改为HTTP后,请求可正常执行;
- 服务器可正确读取证书和密钥文件,无相关错误。
请问如何让该自签名证书正常生效?
解决方案
1. 手动让浏览器信任自签名证书
自签名证书不被浏览器默认信任,这是Chrome报错的直接原因,Firefox的CORS错误本质也是证书验证失败导致请求中断。需将生成的证书添加到浏览器的受信任根证书列表:
Chrome/Edge操作
- 在地址栏输入
chrome://settings/certificates(Edge为edge://settings/certificates)进入证书管理页面; - 切换到「受信任的根证书颁发机构」标签;
- 点击「导入」,选择本地的
cert.pem文件,按向导完成导入,确认将证书加入根证书列表。
Firefox操作
- 在地址栏输入
about:preferences#privacy,滚动到「证书」区域点击「查看证书」; - 切换到「证书机构」标签;
- 点击「导入」,选择
cert.pem文件,勾选「信任由此证书机构颁发的证书」,确认完成导入。
2. 补充IP地址的SAN配置(针对本地IP访问场景)
如果需要用本地网络IP(如192.168.x.x)访问服务器,当前配置仅包含DNS域名的Subject Alternative Name(SAN),需修改req.cnf添加IP条目:
[alt_names] DNS.1 = www.localhost.com DNS.2 = localhost.com DNS.3 = localhost IP.1 = 127.0.0.1 IP.2 = 192.168.xxx.xxx # 替换为你的本地网络IP
修改后重新执行证书生成命令,替换旧的cert.key和cert.pem,再重新导入新证书到浏览器。
3. 明确配置Express服务器的CORS
虽然HTTP环境下请求正常,HTTPS环境建议明确配置CORS中间件,避免跨域请求异常:
首先安装cors依赖:
npm install cors
然后在Express代码中添加CORS配置:
const express = require('express'); const cors = require('cors'); const https = require('https'); const fs = require('fs'); const app = express(); // 配置允许跨域的前端地址 app.use(cors({ origin: 'http://localhost:5173', // 替换为你的Vue项目运行地址 credentials: true })); app.get('/test', (req, res) => { console.log('Test request received'); res.send('Success'); }); // 加载证书文件 const sslOptions = { key: fs.readFileSync('./cert.key'), cert: fs.readFileSync('./cert.pem') }; https.createServer(sslOptions, app).listen(3001, () => { console.log('HTTPS server running on port 3001'); });
4. 验证证书生效
完成上述步骤后,直接访问https://localhost:3001/test(或对应本地IP),浏览器地址栏应显示安全锁标识,此时再通过Vue前端调用接口即可正常执行请求。
内容的提问来源于stack exchange,提问作者GhostOrder
相关产品推荐
相关产品推荐

