You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
3.2 KiB
138 lines
3.2 KiB
2 years ago
|
package main
|
||
|
|
||
|
import (
|
||
|
"crypto/sha1"
|
||
|
"encoding/xml"
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"net/http"
|
||
|
"sort"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/gin-gonic/gin"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
appID = "wxc39301065b66300c"
|
||
|
secret = "7fee3a1cba8c555cf6c4caec4f05844c"
|
||
|
token = "qwertyuiopasdfghjkl"
|
||
|
)
|
||
|
|
||
|
//////
|
||
|
type messageEntity struct {
|
||
|
Signature string `form:"signature"`
|
||
|
Timestamp string `form:"timestamp"`
|
||
|
Nonce string `form:"nonce"`
|
||
|
EchoStr string `form:"echostr"`
|
||
|
}
|
||
|
|
||
|
func (m *messageEntity) CheckSignature(token string) bool {
|
||
|
item := []string{token, m.Timestamp, m.Nonce}
|
||
|
sort.Strings(item)
|
||
|
itemByte := strings.Join(item, "")
|
||
|
signature := fmt.Sprintf("%x", sha1.Sum([]byte(itemByte)))
|
||
|
return signature == m.Signature
|
||
|
}
|
||
|
|
||
|
func Check(c *gin.Context) {
|
||
|
me := &messageEntity{}
|
||
|
me.Signature = c.Query("signature")
|
||
|
me.Timestamp = c.Query("timestamp")
|
||
|
me.Nonce = c.Query("nonce")
|
||
|
me.EchoStr = c.Query("echostr")
|
||
|
log.Println("signature:", me.Signature, "timestamp:", me.Timestamp, "noce:", me.Nonce, "echostr:", me.EchoStr)
|
||
|
if !me.CheckSignature(token) {
|
||
|
log.Println("token is not ok")
|
||
|
c.AbortWithError(http.StatusForbidden, fmt.Errorf("token invalid"))
|
||
|
return
|
||
|
}
|
||
|
c.Next()
|
||
|
}
|
||
|
|
||
|
////
|
||
|
type foucsData struct {
|
||
|
ToUserName string `xml:"ToUserName"`
|
||
|
FromUserName string `xml:"FromUserName"`
|
||
|
CreateTime int64 `xml:"CreateTime"`
|
||
|
MsgType string `xml:"MsgType"`
|
||
|
Event string `xml:"Event"`
|
||
|
}
|
||
|
|
||
|
////
|
||
|
type textMessage struct {
|
||
|
ToUserName string `xml:"ToUserName"`
|
||
|
FromUserName string `xml:"FromUserName"`
|
||
|
CreateTime int64 `xml:"CreateTime"`
|
||
|
MsgType string `xml:"MsgType"`
|
||
|
Content string `xml:"Content"`
|
||
|
}
|
||
|
|
||
|
func cdata(data string)string{
|
||
|
return fmt.Sprintf(`<![CDATA[%s]]>`, data)
|
||
|
}
|
||
|
|
||
|
func handleGet(c *gin.Context) {
|
||
|
me := &messageEntity{}
|
||
|
me.Signature = c.Query("signature")
|
||
|
me.Timestamp = c.Query("timestamp")
|
||
|
me.Nonce = c.Query("nonce")
|
||
|
me.EchoStr = c.Query("echostr")
|
||
|
log.Println("signature:", me.Signature, "timestamp:", me.Timestamp, "noce:", me.Nonce, "echostr:", me.EchoStr)
|
||
|
log.Println("token is ok")
|
||
|
c.String(http.StatusOK, me.EchoStr)
|
||
|
}
|
||
|
func handlePost(c *gin.Context) {
|
||
|
data := foucsData{}
|
||
|
err := c.BindXML(&data)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
log.Println("data: ", data)
|
||
|
openID := c.Query("openid")
|
||
|
log.Println("openid is ", openID)
|
||
|
t := textMessage{
|
||
|
ToUserName: cdata(data.FromUserName),
|
||
|
FromUserName: cdata(data.ToUserName),
|
||
|
CreateTime: time.Now().Unix(),
|
||
|
MsgType: cdata("text"),
|
||
|
Content: cdata("你关注了我!"),
|
||
|
}
|
||
|
d, err := xml.Marshal(&t)
|
||
|
if err != nil {
|
||
|
log.Println("marshar message faild", err)
|
||
|
}
|
||
|
c.String(http.StatusOK, string(d))
|
||
|
}
|
||
|
|
||
|
func handlePut(c *gin.Context) {
|
||
|
data :=foucsData{}
|
||
|
err := c.BindXML(&data)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
log.Println("data: ", data)
|
||
|
c.String(http.StatusOK, "success")
|
||
|
}
|
||
|
|
||
|
func handleDelete(c *gin.Context) {
|
||
|
data := foucsData{}
|
||
|
err := c.BindXML(&data)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
log.Println("data: ", data)
|
||
|
c.String(http.StatusOK, "success")
|
||
|
}
|
||
|
|
||
|
|
||
|
func main() {
|
||
|
engine := gin.Default()
|
||
|
engine.Use(Check)
|
||
|
engine.GET("/api/wechat/signature", handleGet)
|
||
|
engine.POST("/api/wechat/signature", handlePost)
|
||
|
engine.PUT("/api/wechat/signature", handlePut)
|
||
|
engine.DELETE("/api/wechat/signature", handleDelete)
|
||
|
engine.Run("0.0.0.0:15043")
|
||
|
}
|