全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 8 分钟 ✍️ juanwangdev

Gin HTTPS与证书配置

HTTPS 是 Web 安全的基础,Gin 框架支持多种证书配置方式。

基本HTTPS启动

使用证书文件

Go
func main() {
    r := gin.Default()

    // 配置路由
    r.GET("/", func(c *gin.Context) {
        c.String(200, "HTTPS OK")
    })

    // 启动 HTTPS
    r.RunTLS(":443", "server.crt", "server.key")
}

同时支持 HTTP 和 HTTPS

Go
func main() {
    r := gin.Default()
    r.GET("/", func(c *gin.Context) {
        c.String(200, "Hello")
    })

    // HTTP 重定向到 HTTPS
    go func() {
        http.ListenAndServe(":80", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            http.Redirect(w, r, "https://"+r.Host+r.URL.String(), http.StatusMovedPermanently)
        }))
    }()

    // HTTPS 服务
    r.RunTLS(":443", "server.crt", "server.key")
}

自签名证书生成

使用 OpenSSL

Bash
# 生成私钥
openssl genrsa -out server.key 2048

# 生成证书签名请求(CSR)
openssl req -new -key server.key -out server.csr

# 生成自签名证书(有效期365天)
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

# 或者一步生成
openssl req -x509 -newkey rsa:2048 -nodes -keyout server.key -out server.crt -days 365 -subj "/CN=localhost"

代码中生成证书

Go
import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "crypto/x509/pkix"
    "encoding/pem"
    "math/big"
    "os"
    "time"
)

func generateSelfSignedCert() error {
    // 生成私钥
    priv, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        return err
    }

    // 设置证书模板
    template := x509.Certificate{
        SerialNumber: big.NewInt(1),
        Subject: pkix.Name{
            Organization: []string{"My Company"},
        },
        NotBefore: time.Now(),
        NotAfter:  time.Now().Add(365 * 24 * time.Hour),
        KeyUsage:  x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
        ExtKeyUsage: []x509.ExtKeyUsage{
            x509.ExtKeyUsageServerAuth,
        },
        DNSNames: []string{"localhost"},
    }

    // 生成证书
    derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
    if err != nil {
        return err
    }

    // 保存证书
    certOut, _ := os.Create("server.crt")
    pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
    certOut.Close()

    // 保存私钥
    keyOut, _ := os.Create("server.key")
    pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
    keyOut.Close()

    return nil
}

Let's Encrypt 自动证书

使用 autocert

Go
import (
    "golang.org/x/crypto/acme/autocert"
)

func main() {
    r := gin.Default()

    // 配置自动证书管理
    m := &autocert.Manager{
        Prompt:     autocert.AcceptTOS,
        HostPolicy: autocert.HostWhitelist("example.com", "www.example.com"),
        Cache:      autocert.DirCache("certs"),
    }

    // HTTPS 服务器
    s := &http.Server{
        Addr:      ":443",
        Handler:   r,
        TLSConfig: m.TLSConfig(),
    }

    // HTTP 重定向
    go http.ListenAndServe(":80", m.HTTPHandler(nil))

    s.ListenAndServeTLS("", "")
}

Gin 中使用 autocert

Go
func main() {
    r := gin.Default()
    r.GET("/", func(c *gin.Context) {
        c.String(200, "HTTPS with Let's Encrypt")
    })

    m := autocert.Manager{
        Prompt:     autocert.AcceptTOS,
        HostPolicy: autocert.HostWhitelist("yourdomain.com"),
        Cache:      autocert.DirCache("/var/www/.cache"),
    }

    server := &http.Server{
        Addr:      ":443",
        Handler:   r,
        TLSConfig: m.TLSConfig(),
    }

    server.ListenAndServeTLS("", "")
}

TLS 配置优化

Go
import (
    "crypto/tls"
    "net/http"
)

func main() {
    r := gin.Default()

    // 自定义 TLS 配置
    tlsConfig := &tls.Config{
        MinVersion: tls.VersionTLS12, // 最低 TLS 1.2
        CipherSuites: []uint16{
            tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
            tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
            tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
            tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        },
        PreferServerCipherSuites: true,
    }

    server := &http.Server{
        Addr:      ":443",
        Handler:   r,
        TLSConfig: tlsConfig,
    }

    server.ListenAndServeTLS("server.crt", "server.key")
}

HTTPS 安全中间件

Go
func TLSMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        // 强制 HTTPS
        if c.Request.TLS == nil {
            target := "https://" + c.Request.Host + c.Request.URL.String()
            c.Redirect(http.StatusMovedPermanently, target)
            c.Abort()
            return
        }
        c.Next()
    }
}

func SecurityHeaders() gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
        c.Next()
    }
}

func main() {
    r := gin.Default()
    r.Use(TLSMiddleware())
    r.Use(SecurityHeaders())
    r.RunTLS(":443", "server.crt", "server.key")
}

配置方式对比

方式适用场景优点缺点
自签名证书开发测试快速生成浏览器警告
Let's Encrypt生产环境免费、自动续期需公网访问
商业证书企业应用受信任、有保障需付费

注意:生产环境推荐使用 Let's Encrypt 或商业证书,自签名仅用于开发测试。

要点总结

  1. 开发环境:使用 OpenSSL 生成自签名证书
  2. 生产环境:使用 autocert 自动管理 Let's Encrypt 证书
  3. 安全配置:设置 MinVersion TLS 1.2,选择安全加密套件
  4. HTTP 重定向:将 HTTP 流量重定向到 HTTPS
  5. HSTS 头:启用 Strict-Transport-Security 强制 HTTPS

📝 发现内容有误?点击此处直接编辑

← 上一篇 Gin 错误日志收集与告警
下一篇 → Gin JWT认证与鉴权
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库