wx_share.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package utils
  2. import (
  3. "crypto/sha1"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "lzyd-message-api/models"
  9. mathRand "math/rand"
  10. "net/http"
  11. "strconv"
  12. "time"
  13. )
  14. var (
  15. AppID string = "wx47b83b24cf3b5e25"
  16. AppSecret string = "bbcbc2cafbcf6e9cfe9a15aef5444d28"
  17. AccessTokenHost string = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appID=" + AppID + "&secret=" + AppSecret
  18. JsAPITicketHost string = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"
  19. )
  20. func GetWxSign(url string) (err error, data WxSignature){
  21. var (
  22. noncestr, jsapi_ticket, timestamp, signature, signatureStr, access_token string
  23. wxAccessToken WxAccessToken
  24. wxJsApiTicket WxJsApiTicket
  25. wxSignature WxSignature
  26. wxSignRtn WxSignRtn
  27. )
  28. noncestr = RandStringBytes(16)
  29. timestamp = strconv.FormatInt(time.Now().Unix(), 10)
  30. //获取access_token,如果缓存中有,则直接取出数据使用;否则重新调用微信端接口获取
  31. client := &http.Client{}
  32. if models.MemoryCacheVar.Get("access_token") == nil {
  33. request, _ := http.NewRequest("GET", AccessTokenHost, nil)
  34. response, _ := client.Do(request)
  35. defer response.Body.Close()
  36. body, err := ioutil.ReadAll(response.Body)
  37. if err != nil {
  38. wxSignRtn.Code = 1
  39. wxSignRtn.Msg = err.Error()
  40. return err, data
  41. }
  42. err = json.Unmarshal(body, &wxAccessToken)
  43. if err != nil {
  44. wxSignRtn.Code = 1
  45. wxSignRtn.Msg = err.Error()
  46. return err, data
  47. }
  48. if wxAccessToken.Errcode == 0 {
  49. access_token = wxAccessToken.Access_token
  50. } else {
  51. wxSignRtn.Code = 1
  52. wxSignRtn.Msg = wxAccessToken.Errmsg
  53. return err, data
  54. }
  55. models.MemoryCacheVar.Put("access_token", access_token, time.Duration(wxAccessToken.Expires_in)*time.Second)
  56. //获取 jsapi_ticket
  57. requestJs, _ := http.NewRequest("GET", JsAPITicketHost+"?access_token="+access_token+"&type=jsapi", nil)
  58. responseJs, _ := client.Do(requestJs)
  59. defer responseJs.Body.Close()
  60. bodyJs, err := ioutil.ReadAll(responseJs.Body)
  61. if err != nil {
  62. wxSignRtn.Code = 1
  63. wxSignRtn.Msg = err.Error()
  64. return err, data
  65. }
  66. err = json.Unmarshal(bodyJs, &wxJsApiTicket)
  67. if err != nil {
  68. wxSignRtn.Code = 1
  69. wxSignRtn.Msg = err.Error()
  70. return err, data
  71. }
  72. if wxJsApiTicket.Errcode == 0 {
  73. jsapi_ticket = wxJsApiTicket.Ticket
  74. } else {
  75. wxSignRtn.Code = 1
  76. wxSignRtn.Msg = wxJsApiTicket.Errmsg
  77. return err, data
  78. }
  79. models.MemoryCacheVar.Put("jsapi_ticket", jsapi_ticket, time.Duration(wxJsApiTicket.Expires_in)*time.Second)
  80. } else {
  81. //缓存中存在access_token,直接读取
  82. access_token = models.MemoryCacheVar.Get("access_token").(*models.Item).Value
  83. jsapi_ticket = models.MemoryCacheVar.Get("jsapi_ticket").(*models.Item).Value
  84. }
  85. //fmt.Println("access_token:",access_token)
  86. //fmt.Println("jsapi_ticket:",jsapi_ticket)
  87. // 获取 signature
  88. signatureStr = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url
  89. signature = GetSha1(signatureStr)
  90. wxSignature.Url = url
  91. wxSignature.Noncestr = noncestr
  92. wxSignature.Timestamp = timestamp
  93. wxSignature.Signature = signature
  94. wxSignature.AppID = AppID
  95. // 返回前端需要的数据
  96. //wxSignRtn.Code = 0
  97. //wxSignRtn.Msg = "success"
  98. //wxSignRtn.Data = wxSignature
  99. return err, wxSignature
  100. }
  101. //生成指定长度的字符串
  102. func RandStringBytes(n int) string {
  103. const letterBytes = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  104. b := make([]byte, n)
  105. for i := range b {
  106. b[i] = letterBytes[mathRand.Intn(len(letterBytes))]
  107. }
  108. return string(b)
  109. }
  110. //SHA1加密
  111. func GetSha1(data string) string {
  112. t := sha1.New()
  113. io.WriteString(t, data)
  114. return fmt.Sprintf("%x", t.Sum(nil))
  115. }
  116. type WxAccessToken struct {
  117. Access_token string `json:"access_token"`
  118. Expires_in int `json:"expires_in"`
  119. Errcode int `json:"errcode"`
  120. Errmsg string `json:"errmsg"`
  121. }
  122. type WxJsApiTicket struct {
  123. Ticket string `json:"ticket"`
  124. Expires_in int `json:"expires_in"`
  125. Errcode int `json:"errcode"`
  126. Errmsg string `json:"errmsg"`
  127. }
  128. type WxSignature struct {
  129. Noncestr string `json:"noncestr"`
  130. Timestamp string `json:"timestamp"`
  131. Url string `json:"url"`
  132. Signature string `json:"signature"`
  133. AppID string `json:"appId"`
  134. }
  135. type WxSignRtn struct {
  136. Code int `json:"code"`
  137. Msg string `json:"msg"`
  138. Data WxSignature `json:"data"`
  139. }