目录

[Go] mTLS client示例

环境

  • go 1.20

GET请求示例

package main

import (
	"crypto/tls"
	"crypto/x509"
	"io"
	"log"
	"net/http"
	"os"
)

func main() {
	// 加载证书和密钥
	cert, err := tls.LoadX509KeyPair("client.crt", "client.key")
	if err != nil {
		log.Fatal(err)
	}

	// 加载服务器的根证书
	caCert, err := os.ReadFile("ca.crt")
	if err != nil {
		log.Fatal(err)
	}
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(caCert)

	// 配置TLS客户端
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
		RootCAs:      caCertPool,
	}

	// 创建HTTP客户端
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: tlsConfig,
		},
	}

	// 发送HTTP请求
	resp, err := client.Get("https://example.com")
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	// 处理响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	log.Println(string(body))
}
  • 在这个示例代码中,首先使用tls.LoadX509KeyPair函数加载客户端的证书和密钥,然后使用os.ReadFile函数加载服务器的根证书,并将其添加到一个x509.CertPool对象中。然后,创建一个tls.Config对象,其中包含客户端的证书和服务器的根证书,并将其传递给http.Transport对象的TLSClientConfig字段。最后,创建一个http.Client对象,并使用它来发送HTTP请求。
  • 需要注意的是,示例代码中使用的是http.Get函数发送HTTP请求。如果需要发送其他类型的请求,可以使用http.NewRequest函数创建一个新的请求对象,然后调用client.Do方法来发送请求。

POST请求示例

package main

import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"io"
	"log"
	"net/http"
	"os"
)

func main() {
	// 加载证书和密钥
	cert, err := tls.LoadX509KeyPair("client.crt", "client.key")
	if err != nil {
		log.Fatal(err)
	}

	// 加载服务器的根证书
	caCert, err := os.ReadFile("ca.crt")
	if err != nil {
		log.Fatal(err)
	}
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(caCert)

	// 配置TLS客户端
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
		RootCAs:      caCertPool,
	}

	// 创建HTTP客户端
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: tlsConfig,
		},
	}

	// 准备POST请求数据(与GET请求不同的部分)
	data := []byte(`{"name":"John Doe","age":30}`)
	req, err := http.NewRequest("POST", "https://example.com/api", bytes.NewBuffer(data))
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("Content-Type", "application/json")

	// 发送HTTP请求
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	// 处理响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	log.Println(string(body))
}
  • 需要注意的是,在创建请求对象时,需要将请求数据作为bytes.Buffer对象传递给http.NewRequest函数。在设置请求头时,我们设置了Content-Type为application/json,这表明我们要发送的是一个JSON格式的数据。