package utils import ( "crypto/sha1" "encoding/json" "fmt" "io" "io/ioutil" "lzyd-message-api/models" mathRand "math/rand" "net/http" "strconv" "time" ) var ( AppID string = "wx47b83b24cf3b5e25" AppSecret string = "bbcbc2cafbcf6e9cfe9a15aef5444d28" AccessTokenHost string = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appID=" + AppID + "&secret=" + AppSecret JsAPITicketHost string = "https://api.weixin.qq.com/cgi-bin/ticket/getticket" ) func GetWxSign(url string) (err error, data WxSignature){ var ( noncestr, jsapi_ticket, timestamp, signature, signatureStr, access_token string wxAccessToken WxAccessToken wxJsApiTicket WxJsApiTicket wxSignature WxSignature wxSignRtn WxSignRtn ) noncestr = RandStringBytes(16) timestamp = strconv.FormatInt(time.Now().Unix(), 10) //获取access_token,如果缓存中有,则直接取出数据使用;否则重新调用微信端接口获取 client := &http.Client{} if models.MemoryCacheVar.Get("access_token") == nil { request, _ := http.NewRequest("GET", AccessTokenHost, nil) response, _ := client.Do(request) defer response.Body.Close() body, err := ioutil.ReadAll(response.Body) if err != nil { wxSignRtn.Code = 1 wxSignRtn.Msg = err.Error() return err, data } err = json.Unmarshal(body, &wxAccessToken) if err != nil { wxSignRtn.Code = 1 wxSignRtn.Msg = err.Error() return err, data } if wxAccessToken.Errcode == 0 { access_token = wxAccessToken.Access_token } else { wxSignRtn.Code = 1 wxSignRtn.Msg = wxAccessToken.Errmsg return err, data } models.MemoryCacheVar.Put("access_token", access_token, time.Duration(wxAccessToken.Expires_in)*time.Second) //获取 jsapi_ticket requestJs, _ := http.NewRequest("GET", JsAPITicketHost+"?access_token="+access_token+"&type=jsapi", nil) responseJs, _ := client.Do(requestJs) defer responseJs.Body.Close() bodyJs, err := ioutil.ReadAll(responseJs.Body) if err != nil { wxSignRtn.Code = 1 wxSignRtn.Msg = err.Error() return err, data } err = json.Unmarshal(bodyJs, &wxJsApiTicket) if err != nil { wxSignRtn.Code = 1 wxSignRtn.Msg = err.Error() return err, data } if wxJsApiTicket.Errcode == 0 { jsapi_ticket = wxJsApiTicket.Ticket } else { wxSignRtn.Code = 1 wxSignRtn.Msg = wxJsApiTicket.Errmsg return err, data } models.MemoryCacheVar.Put("jsapi_ticket", jsapi_ticket, time.Duration(wxJsApiTicket.Expires_in)*time.Second) } else { //缓存中存在access_token,直接读取 access_token = models.MemoryCacheVar.Get("access_token").(*models.Item).Value jsapi_ticket = models.MemoryCacheVar.Get("jsapi_ticket").(*models.Item).Value } //fmt.Println("access_token:",access_token) //fmt.Println("jsapi_ticket:",jsapi_ticket) // 获取 signature signatureStr = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url signature = GetSha1(signatureStr) wxSignature.Url = url wxSignature.Noncestr = noncestr wxSignature.Timestamp = timestamp wxSignature.Signature = signature wxSignature.AppID = AppID // 返回前端需要的数据 //wxSignRtn.Code = 0 //wxSignRtn.Msg = "success" //wxSignRtn.Data = wxSignature return err, wxSignature } //生成指定长度的字符串 func RandStringBytes(n int) string { const letterBytes = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" b := make([]byte, n) for i := range b { b[i] = letterBytes[mathRand.Intn(len(letterBytes))] } return string(b) } //SHA1加密 func GetSha1(data string) string { t := sha1.New() io.WriteString(t, data) return fmt.Sprintf("%x", t.Sum(nil)) } type WxAccessToken struct { Access_token string `json:"access_token"` Expires_in int `json:"expires_in"` Errcode int `json:"errcode"` Errmsg string `json:"errmsg"` } type WxJsApiTicket struct { Ticket string `json:"ticket"` Expires_in int `json:"expires_in"` Errcode int `json:"errcode"` Errmsg string `json:"errmsg"` } type WxSignature struct { Noncestr string `json:"noncestr"` Timestamp string `json:"timestamp"` Url string `json:"url"` Signature string `json:"signature"` AppID string `json:"appId"` } type WxSignRtn struct { Code int `json:"code"` Msg string `json:"msg"` Data WxSignature `json:"data"` }