wechat.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package auth
  2. import (
  3. "encoding/json"
  4. "eta/eta_mini_ht_api/models"
  5. "fmt"
  6. "github.com/silenceper/wechat/v2"
  7. "github.com/silenceper/wechat/v2/cache"
  8. "gorm.io/gorm"
  9. "io"
  10. "net/http"
  11. "time"
  12. "github.com/silenceper/wechat/v2/credential"
  13. "github.com/silenceper/wechat/v2/officialaccount"
  14. "github.com/silenceper/wechat/v2/officialaccount/config"
  15. "github.com/silenceper/wechat/v2/officialaccount/js"
  16. "github.com/silenceper/wechat/v2/officialaccount/user"
  17. )
  18. var (
  19. WxAppId string
  20. WxAppSecret string
  21. )
  22. // 海通公众号配置
  23. const (
  24. HT_WX_APPID = "wxf0dfb65c325fee66"
  25. HT_WX_APP_SECRET = "4f2a6c4f9b0a9dee08d1b3b316f33228"
  26. )
  27. type WechatAccessToken struct {
  28. }
  29. var DefaultKey = "zcmRedis"
  30. // GetAccessToken 获取accessToken
  31. func (wechat WechatAccessToken) GetAccessToken() (accessToken string, err error) {
  32. wxToken, err := models.GetWxTokenById()
  33. var isRegister bool
  34. if err != nil {
  35. if err == gorm.ErrRecordNotFound {
  36. isRegister = true
  37. } else {
  38. return
  39. }
  40. }
  41. if isRegister {
  42. tmpAccessToken, expires, tmpErr := getTokenFromServer(HT_WX_APPID, HT_WX_APP_SECRET)
  43. if tmpErr != nil {
  44. err = tmpErr
  45. return
  46. }
  47. token := new(models.WxToken)
  48. token.AccessToken = tmpAccessToken
  49. token.ExpiresIn = expires
  50. err = models.RegisterWxToken(token)
  51. if err != nil {
  52. return "", err
  53. }
  54. accessToken = tmpAccessToken
  55. return
  56. }
  57. //如果300s就要过期了,那么就去刷新accessToken
  58. if wxToken.ExpiresIn < time.Now().Unix()+300 {
  59. tmpAccessToken, expires, tmpErr := getTokenFromServer(HT_WX_APPID, HT_WX_APP_SECRET)
  60. if tmpErr != nil {
  61. err = tmpErr
  62. return
  63. }
  64. expiresIn := time.Now().Unix() + expires - 600 //快过期前10分钟就刷新掉
  65. models.UpdateWxToken(tmpAccessToken, expiresIn)
  66. accessToken = tmpAccessToken
  67. }
  68. accessToken = wxToken.AccessToken
  69. return
  70. }
  71. // getTokenFromServer 服务端获取accessToken
  72. func getTokenFromServer(appid, wxSecret string) (accessToken string, expires int64, err error) {
  73. apiUrl := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
  74. resAccessToken, err := credential.GetTokenFromServer(fmt.Sprintf(apiUrl, appid, wxSecret))
  75. if err != nil {
  76. return
  77. }
  78. expires = resAccessToken.ExpiresIn
  79. accessToken = resAccessToken.AccessToken
  80. return
  81. }
  82. func GetWxChat() (officialAccount *officialaccount.OfficialAccount) {
  83. wc := wechat.NewWechat()
  84. memory := cache.NewMemory()
  85. conf := &config.Config{
  86. AppID: HT_WX_APPID,
  87. AppSecret: HT_WX_APP_SECRET,
  88. Token: "",
  89. EncodingAESKey: "",
  90. Cache: memory,
  91. }
  92. officialAccount = wc.GetOfficialAccount(conf)
  93. wechatAccessToken := &WechatAccessToken{}
  94. officialAccount.SetAccessTokenHandle(wechatAccessToken)
  95. return
  96. }
  97. // GetUserInfo 获取微信用户详情
  98. func GetUserInfo(openid string) (userInfo *user.Info, err error) {
  99. wechatClient := GetWxChat()
  100. userClient := wechatClient.GetUser()
  101. userInfo, err = userClient.GetUserInfo(openid)
  102. return
  103. }
  104. // GetJsConfig 获取公众号jsConfig
  105. func GetJsConfig(signUrl string) (jsConf *js.Config, err error) {
  106. wechatClient := GetWxChat()
  107. j := wechatClient.GetJs()
  108. jsConf, err = j.GetConfig(signUrl)
  109. return
  110. }
  111. type WxUserInfo struct {
  112. OpenId string `json:"openid"`
  113. AccessToken string `json:"access_token"`
  114. RefreshToken string `json:"refresh_token"`
  115. Scope string `json:"scope"`
  116. ErrCode int
  117. ErrMsg string
  118. }
  119. func GetWxUserInfo(code string) (info *WxUserInfo, err error) {
  120. httpUrl := `https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code`
  121. httpUrl = fmt.Sprintf(httpUrl, HT_WX_APPID, HT_WX_APP_SECRET, code)
  122. client := http.Client{}
  123. wxReq, err := http.NewRequest("GET", httpUrl, nil)
  124. if err != nil {
  125. return
  126. }
  127. response, err := client.Do(wxReq)
  128. if err != nil {
  129. return
  130. }
  131. defer response.Body.Close()
  132. body, err := io.ReadAll(response.Body)
  133. if err != nil {
  134. return
  135. }
  136. if err = json.Unmarshal(body, &info); err != nil {
  137. return
  138. }
  139. return
  140. }
  141. // GetUserInfo 获取微信用户详情
  142. func GetWxUserDetail(openid string) (userInfo *user.Info, err error) {
  143. wechatClient := GetWxChat()
  144. userClient := wechatClient.GetUser()
  145. userInfo, err = userClient.GetUserInfo(openid)
  146. return
  147. }