基于HTTPS的Node.js+Express服务器ATS配置问题求助
解决Apple ATS与自签名HTTPS服务器的适配问题
嘿,这个问题我太熟了!你碰到的kCFStreamErrorDomainSSL, -9802错误,核心原因就是Apple的ATS(应用传输安全)不信任你的自签名HTTPS证书——ATS默认只接受由受信任根证书颁发机构(CA)签发的证书。下面分开发测试和生产上线两种场景,给你一步步解决:
一、开发环境:临时放宽ATS限制(仅用于测试)
如果只是本地开发测试,可以修改Info.plist的ATS配置,针对你的服务器IP做定向放宽,别用全局关闭ATS的方式(苹果审核会卡):
替换成这份正确的ATS配置
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>172.16.53.247</key> <!-- 改成你的服务器IP --> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSTemporaryExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> <key>NSTemporaryExceptionRequiresForwardSecrecy</key> <false/> </dict> </dict> </key>
划重点:带
NSTemporaryException前缀的配置是临时的,上线前必须删掉,改用正规证书。
二、服务端:补全证书和代码的坑
你的Node.js代码还有两个关键问题,不解决的话就算ATS配置对了也会失败:
1. 重新生成符合ATS要求的自签名证书
原来的证书可能缺少主题备用名称(SAN),ATS现在要求证书必须包含匹配的SAN字段(不能只靠CN),用这条命令重新生成:
openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes \ -keyout server-key.pem -out server-cert.pem \ -subj "/CN=172.16.53.247" \ -addext "subjectAltName=IP:172.16.53.247" \ -addext "keyUsage=digitalSignature,keyEncipherment" \ -addext "extendedKeyUsage=serverAuth"
2. 完善Node.js服务端配置
你原来的代码没加JSON解析中间件,POST的JSON数据根本没法被服务端接收,而且HTTPS配置也没对齐ATS的加密要求,改成这样:
const fs = require('fs'); const https = require('https'); const express = require('express'); const port = 8989; const options = { key: fs.readFileSync('./Config/server-key.pem'), cert: fs.readFileSync('./Config/server-cert.pem'), // 强制使用ATS要求的TLS 1.2+ minVersion: 'TLSv1.2', // 指定符合ATS标准的加密套件 ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256', honorCipherOrder: true }; var app = express(); // 必须加这个中间件,才能解析POST过来的JSON数据! app.use(express.json()); var server = https.createServer(options, app).listen(port, function(){ console.log("Express server listening on port " + port); }); app.get('/', function (req, res) { res.writeHead(200); res.end("hello world\n"); }); // 示例login接口,现在能正确接收JSON参数了 app.post('/login', function(req, res) { const { Username, Password } = req.body; // 这里写你的登录逻辑 res.json({ return: 1 }); // 返回示例数据 }); module.exports = app;
三、生产环境:用正规CA签发的证书
如果是要上线的应用,别用自签名证书了,去申请一个Apple信任的CA签发的证书(比如Let's Encrypt的免费证书),此时ATS不需要任何额外配置,默认就能通过验证。
验证配置是否生效
用Apple官方的nscurl工具测试一下,确保ATS能正常通过:
nscurl --ats-diagnostics https://172.16.53.247:8989/login
如果所有测试项都显示Result : PASS,就说明配置没问题了。
内容的提问来源于stack exchange,提问作者riki
相关产品推荐
相关产品推荐

