go 验证微信公众号服务器配置

  • 内容
  • 评论
  • 相关

最近接触了一下微信公众号开发,刚好很久很久之前申请过一个公众号,看了下API文档,用go实现了一个简单的验证微信服务器的功能。

下面的代码可以通过微信服务器的验证。

只需要配置 config.json文件即可,config.json和main.go文件处于同一目录层级,config.json格式文件配置如下:

1
2
3
4
{
    "token":"XXX",
    "port":"7001"
}

其中token需要在微信公众平台获取相关信息。

port 则是你使用的监听接口,nginx反向代理到该端口。

运行时,输入

go run main.go config.json 即可

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package main
 
import (
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sort"
	"strings"
)
 
const wx_params_timestamp string = "timestamp"
const wx_params_signature string = "signature"
const wx_params_nonce string = "nonce"
const wx_params_echostr string = "echostr"
 
const wx_access_token_key string = "access_token"
const wx_access_token_time_key string = "expires_in"
 
const wx_access_token_error_code string = "errcode"
const wx_access_token_error_msg string = "errmsg"
 
//
var wx_gzh_token_str string
 
type SConsConfig struct {
	Token string `json:"token"`
	Port  string `json:"port"`
}
 
func NewJsonStruct() *SConsConfig {
	return &SConsConfig{}
}
 
func (jst *SConsConfig) LoadConfig(fileName string, v interface{}) {
	data, err := ioutil.ReadFile(fileName)
	if err != nil {
		return
	}
	err = json.Unmarshal(data, v)
	if err != nil {
		return
	}
}
func ParseSconsConfig(fileName string) (v SConsConfig, err error) {
	JsonParse := NewJsonStruct()
	v = SConsConfig{}
	JsonParse.LoadConfig(fileName, &v)
	return v, nil
}
 
func makeSignature(timestamp string, nonce string) string {
 
	//1. 将 plat_token、timestamp、nonce三个参数进行字典序排序
	sl := []string{wx_gzh_token_str, timestamp, nonce}
	sort.Strings(sl)
	//2. 将三个参数字符串拼接成一个字符串进行sha1加密
	s := sha1.New()
	io.WriteString(s, strings.Join(sl, ""))
 
	return fmt.Sprintf("%x", s.Sum(nil))
}
 
func CheckSignature(r *http.Request) (bool, string) {
	r.ParseForm()
	log.Println("start parse require params")
	for k, v := range r.Form {
		log.Println("k=", k, ",v=", v)
	}
	timestamp := ""
	if len(r.Form[wx_params_timestamp]) > 0 {
		timestamp = r.Form[wx_params_timestamp][0]
		log.Println(wx_params_timestamp, "=", timestamp)
	}
	signature := ""
	if len(r.Form[wx_params_signature]) > 0 {
		signature = r.Form[wx_params_signature][0]
		log.Println(wx_params_signature, "=", signature)
	}
 
	nonce := ""
	if len(r.Form[wx_params_nonce]) > 0 {
		nonce = r.Form[wx_params_nonce][0]
		log.Println(wx_params_nonce, "=", nonce)
	}
 
	echostr := ""
	if len(r.Form[wx_params_echostr]) > 0 {
		echostr = r.Form[wx_params_echostr][0]
		log.Println(wx_params_echostr, "=", echostr)
	}
 
	my_signature := makeSignature(timestamp, nonce)
	log.Println("my signature is ", my_signature)
 
	if signature == my_signature {
		return true, echostr
	} else {
		return false, echostr
	}
}
 
type wx_token_require_handler struct{}
 
func (h *wx_token_require_handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Println("check require is from wx server or not")
 
	flag, echostr := CheckSignature(r)
 
	if flag {
		w.Write([]byte(echostr))
	} else {
		log.Println("require not from wx server,please check")
	}
}
 
func InitGlobal() {
	wx_gzh_token_str = ""
}
 
func HttpCheckServer(checkPort string) {
	http.Handle("/", &wx_token_require_handler{})
	port := "0.0.0.0:" + checkPort
	log.Println("start listen port:", checkPort)
	http.ListenAndServe(port, nil)
}
 
func main() {
 
	log.Println("start gzh token center")
	log.Println("param format: port srv_port")
 
	arg_num := len(os.Args)
 
	if arg_num < 2 {
		log.Println("please input the port and token str")
		os.Exit(1)
	}
 
	configFile := os.Args[1]
 
	config, err := ParseSconsConfig(configFile)
 
	if nil != err {
		log.Println("parse config error,err=", err)
		os.Exit(1)
	}
	InitGlobal()
	wx_gzh_token_str = config.Token
 
	HttpCheckServer(config.Port)
}

原创文章,转载请注明: 转载自专注游戏开发

本文链接地址: go 验证微信公众号服务器配置

评论

0条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注