接收微信消息的接口内容:
//"r"为*http.Request
r.ParseForm()
timestamp := strings.Join(r.Form["timestamp"], "")
nonce := strings.Join(r.Form["nonce"], "")
signature := strings.Join(r.Form["signature"], "")
encryptType := strings.Join(r.Form["encrypt_type"], "")
msgSignature := strings.Join(r.Form["msg_signature"], "")
if !wechat.ValidateUrl(timestamp, nonce, signature) {
wmm.log.AppendObj(nil, "Wechat Message Service: this http request is not from Wechat platform!")
return
}
//微信安全模式更改/首次添加url,需要验证,将参数原样写会即可
var es string
if e = req.ParseGet("echostr", &es); e != nil {
}
if es != "" {
//todo 将参数值es原先写回即可
return
}
if r.Method == "POST" {
if encryptType == "aes" {
encryptRequestBody := wechat.ParseEncryptRequestBody(r)
// Validate mstBody signature
if !wechat.ValidateMsg(timestamp, nonce, encryptRequestBody.Encrypt, msgSignature) {
return
}
// Decode base64
cipherData, err := base64.StdEncoding.DecodeString(encryptRequestBody.Encrypt)
if err != nil {
return
}
// AES Decrypt
plainData, err := wechat.AesDecrypt(cipherData, wechat.AesKey)
if err != nil {
return
}
//封装struct
textRequestBody, err := wechat.ParseEncryptTextRequestBody(plainData)
if err != nil {
return
}
var url string
tp := textRequestBody.MsgType
if tp == "text" && textRequestBody.Content == "【收到不支持的消息类型,暂无法显示】" {
//安全模式下向用户回复消息也需要加密
respBody, e := wechat.MakeEncryptResponseBody(textRequestBody.ToUserName, textRequestBody.FromUserName, "一些回复给用户的消息", nonce, timestamp)
if e != nil {
return e
}
//此处return NewSimpleError是一个对返回值处理的封装,返回xml格式消息,并不是返回错误
return service.NewSimpleError(service.SERVER_WRITE_XML, string(respBody))
}
if tp == "event" {
//某个类型的消息暂时后台不作处理,也需要向微信服务器做出响应
return service.NewSimpleError(service.SERVER_WRITE_TEXT, "success")
}
}
return service.NewSimpleError(service.SERVER_WRITE_TEXT, "success")
附:微信消息加解密工具包(GoLang)
package wechat
//微信消息加解密工具包
const (
//以下均为公众号管理后台设置项
token = "XXXXXXXX"
appID = "XXXXXXXXXX"
encodingAESKey = "XXXXXXXXXXXXXXX"
)
var AesKey []byte
func EncodingAESKey2AESKey(encodingKey string) []byte {
data, _ := base64.StdEncoding.DecodeString(encodingKey + "=")
return data
}
func init() {
AesKey = EncodingAESKey2AESKey(encodingAESKey)
}
type TextRequestBody struct {
XMLName xml.Name `xml:"xml"`
ToUserName string
FromUserName string
CreateTime time.Duration
MsgType string
Url string
PicUrl string
MediaId string
ThumbMediaId string
Content string
MsgId int
Location_X string
Location_Y string
Label string
}
type TextResponseBody struct {
XMLName xml.Name `xml:"xml"`
ToUserName CDATAText
FromUserName CDATAText
CreateTime string
MsgType CDATAText
Content CDATAText
}
type EncryptRequestBody struct {
XMLName xml.Name `xml:"xml"`
ToUserName string
Encrypt string
}
type EncryptResponseBody struct {
XMLName xml.Name `xml:"xml"`
Encrypt CDATAText
MsgSignature CDATAText
TimeStamp string
Nonce CDATAText
}
type EncryptResponseBody1 struct {
XMLName