gin.default() 不支持 https,必须用 runtls(":443", "cert.pem", "key.pem") 显式启用;证书需含 san(如 localhost)、密钥与证书配对、路径正确,且端口建议用 :443 或 :8443。

为什么 gin.Default() 启动后访问 HTTPS 会失败
因为 gin.Default() 只启动 HTTP 服务,默认不处理 TLS。直接用浏览器访问 https://localhost:8080 会报“连接被拒绝”或“ERR_SSL_PROTOCOL_ERROR”,不是证书问题,而是服务压根没监听 HTTPS 端口。
- 必须显式调用
router.RunTLS(":443", "cert.pem", "key.pem")才启用 TLS - 端口不能是
:8080这类非特权端口——自签证书下浏览器对非 443 端口会更严格校验,建议先用:443测试(需 root 权限)或:8443(无需 root) -
RunTLS内部使用 Go 标准库http.Server的ListenAndServeTLS,不支持 ALPN(所以无法跑 gRPC-Web 或 HTTP/2 的某些特性,除非手动构造http.Server)
如何生成可用的自签名证书(含 SAN)
浏览器现在基本拒绝没有 Subject Alternative Name(SAN)的证书,哪怕 CN 是 localhost。用 OpenSSL 生成时必须包含 -subj + -extfile,否则 Chrome/Firefox 直接显示“您的连接不是私密连接”。
- 创建
ssl.conf文件,内容含subjectAltName = DNS:localhost,IP:127.0.0.1 - 执行:
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout key.pem -out cert.pem -days 365 -config ssl.conf -subj "/CN=localhost"
- 证书路径必须是绝对路径或相对于二进制所在目录;Gin 不接受嵌入式证书或 PEM 内联字符串
- Windows 上若提示“找不到 openssl”,推荐用 Git Bash 或直接下载 OpenSSL for Windows
RunTLS 报错 crypto/tls: private key does not match public key
这是最常见的证书加载失败原因,不是格式错,而是密钥和证书不配对。Gin 在调用 http.ListenAndServeTLS 前不做校验,错误会在首次 TLS 握手时爆发,表现为服务启动成功但浏览器打不开、curl 提示 SSL routines::wrong version number 或直接 timeout。
- 用命令验证配对:
openssl x509 -noout -modulus -in cert.pem | openssl md5<br>openssl rsa -noout -modulus -in key.pem | openssl md5
两行输出必须一致 - 不要重命名
.pem为.crt或.key—— Gin 只认内容,不看扩展名,但容易误导自己 - 如果用
go run启动,确保cert.pem和key.pem在当前工作目录;用go build && ./app时,它们得放在可执行文件同级目录
开发时绕过浏览器证书警告的临时方案
自签证书必然触发浏览器警告,但你不需要每次都点“高级→继续前往”。有三个实际可用方式:
- Chrome 访问
chrome://flags/#unsafely-treat-insecure-origin-as-secure,添加https://localhost:8443并启用该 flag(仅限本地开发) - curl 测试时加
-k(跳过证书验证),例如:curl -k https://localhost:8443/ping - 前端 fetch 请求若走 HTTPS,需在
package.json或 vite.config.ts 中配置代理到http://localhost:8080,避免混合内容(Mixed Content)被浏览器拦截——这不是 Gin 的问题,但常被误认为 TLS 配置失败
真正麻烦的不是生成证书,而是证书与密钥是否匹配、路径是否正确、端口是否被占用,以及浏览器对 SAN 的强制要求。这三处出错,90% 的“HTTPS 不生效”问题就解决了。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











