欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Golang 原生实现 HTTPS POST json 请求

程序员文章站 2022-06-22 23:47:16
...

https 证书

使用 openssl 来生成私人证书

# 生成客户端私钥 (生成CA私钥)
openssl genrsa -out ca.key 2048 
# 生成CA证书
openssl req -x509 -new -nodes -key ca.key -subj "/CN=tonybai.com" -days 5000 -out ca.crt

# 生成服务端私钥
openssl genrsa -out server.key 2048
# 生成证书请求文件
openssl req -new -key server.key -subj "/CN=localhost" -out server.csr
# 根据CA的私钥和上面的证书请求文件生成服务端证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000

https server

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
)

type RequestBody struct {
	Arr []string `json:"arr"`
}

func postHandler(w http.ResponseWriter, r *http.Request)  {
	defer r.Body.Close()

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Fatal("read request error")
	}

	fmt.Println("response Body:", string(body))
	var req RequestBody
	if err := json.Unmarshal(body, &req); err != nil {
		log.Fatal("unmarshal request error")
	}
	fmt.Println(req.Arr)

	retJson,_ := json.Marshal(req.Arr)
	io.WriteString(w, string(retJson))
}

func indexHandler(w http.ResponseWriter, r *http.Request)  {
	fmt.Println("indexHandler")
	fmt.Fprintf(w, "welcome https")
}

func main()  {
	http.HandleFunc("/", indexHandler)
	http.HandleFunc("/post", postHandler)
	http.ListenAndServeTLS(":8080", "server.crt", "server.key", nil)
}

https client

package main

import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)


func httpsPost(addr string, json []byte, contentType string)  {
	// CertPool 代表一个证书集合/证书池。
	// 创建一个 CertPool
	pool := x509.NewCertPool()
	caCertPath := "ca.crt"
	// 调用 ca.crt 文件
	caCrt, err := ioutil.ReadFile(caCertPath)
	if err != nil {
		fmt.Println("ReadFile err:", err)
		return
	}
	// 解析证书
	pool.AppendCertsFromPEM(caCrt)
	tr := &http.Transport{
		// 把从服务器传过来的非叶子证书,添加到中间证书的池中,使用设置的根证书和中间证书对叶子证书进行验证。
		TLSClientConfig: &tls.Config{RootCAs: pool},
		// 客户端跳过对证书的校验
		//TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	resp, err := client.Post(addr, contentType, bytes.NewBuffer(json))
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	fmt.Println("response Status:", resp.Status)
	fmt.Println("response Headers:", resp.Header)
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	fmt.Println("response Body:", string(body))
}

type requestBody struct {
	Arr []string `json:"arr"`
}

func main()  {
	request := &requestBody{Arr: []string{"123", "345", "23456"}}
	addr := "https://localhost:8080/post"
	marshal, err := json.Marshal(request)
	if err != nil {
		log.Fatalf("marshal error %v", request)
	}
	contentType := "application/json"

	httpsPost(addr, marshal, contentType)
}

参考文章:golang 的http/https server与client

相关标签: Go # Go基础 go