Swift Socket.io客户端连接Node.js服务端触发SSL错误如何解决?
问题原因
- 核心问题:你当前的Node.js服务启动的是普通HTTP服务,没有配置任何SSL证书,但客户端使用
https协议发起请求,自然无法完成SSL握手建立连接。 - 你在Socket.io服务端配置的
rejectUnauthorized: false无效:该参数仅适用于Socket.io作为客户端连接外部HTTPS服务的场景,服务端配置不识别该参数,不会生效。 - 若你修改ATS配置后仍报错,大概率是ATS的例外规则配置不正确,没有覆盖localhost的HTTP访问权限。
解决方案
方案1:本地开发直接使用HTTP(最简便)
- 修改iOS客户端Socket连接地址,将
https://localhost:8080改为http://localhost:8080 - 正确配置Info.plist的ATS规则,右键Info.plist选择「Open As - Source Code」,添加以下配置:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsLocalNetworking</key> <true/> </dict>
该配置允许本地网络的HTTP请求,不需要添加全局不安全HTTP访问权限,安全性更高。
方案2:本地使用HTTPS测试
如果必须模拟HTTPS环境测试,按以下步骤操作:
- 生成本地自签SSL证书:可以使用
mkcert工具生成本地受信任的证书,得到cert.pem和key.pem两个文件 - 修改Node.js服务端代码,使用HTTPS模块启动服务:
const express = require('express'); const https = require('https'); const fs = require('fs'); const app = express(); const port = process.env.PORT || 8080; // 读取证书文件 const options = { key: fs.readFileSync('key.pem'), cert: fs.readFileSync('cert.pem') }; // 用HTTPS启动服务 const server = https.createServer(options, app).listen(port, () => { console.log(`A Node Js API is listening on port: ${port}`); }); const io = require("socket.io")(server); // 其余Socket监听逻辑保持不变
- 将生成的证书安装到你测试用的iOS模拟器/真机上,并且在「设置 - 通用 - 关于本机 - 证书信任设置」中开启该证书的完全信任权限
- 修改iOS客户端SocketManager的配置,添加自签证书信任参数:
static let manager = SocketManager(socketURL: URL(string: "https://localhost:8080")!, config: [.log(true), .compress, .selfSigned(true)])
生产环境注意事项
生产环境不要使用自签证书,请使用正规CA机构颁发的SSL证书部署到服务端,不需要额外配置客户端信任参数即可正常连接。
内容的提问来源于stack exchange,提问作者Billy Bob
相关产品推荐
相关产品推荐

