default_js_ticket.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package credential
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "sync"
  6. "time"
  7. "github.com/silenceper/wechat/v2/cache"
  8. "github.com/silenceper/wechat/v2/util"
  9. )
  10. //获取ticket的url
  11. const getTicketURL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi"
  12. //DefaultJsTicket 默认获取js ticket方法
  13. type DefaultJsTicket struct {
  14. appID string
  15. cacheKeyPrefix string
  16. cache cache.Cache
  17. //jsAPITicket 读写锁 同一个AppID一个
  18. jsAPITicketLock *sync.Mutex
  19. }
  20. //NewDefaultJsTicket new
  21. func NewDefaultJsTicket(appID string, cacheKeyPrefix string, cache cache.Cache) JsTicketHandle {
  22. return &DefaultJsTicket{
  23. appID: appID,
  24. cache: cache,
  25. cacheKeyPrefix: cacheKeyPrefix,
  26. jsAPITicketLock: new(sync.Mutex),
  27. }
  28. }
  29. // ResTicket 请求jsapi_tikcet返回结果
  30. type ResTicket struct {
  31. util.CommonError
  32. Ticket string `json:"ticket"`
  33. ExpiresIn int64 `json:"expires_in"`
  34. }
  35. //GetTicket 获取jsapi_ticket
  36. func (js *DefaultJsTicket) GetTicket(accessToken string) (ticketStr string, err error) {
  37. js.jsAPITicketLock.Lock()
  38. defer js.jsAPITicketLock.Unlock()
  39. //先从cache中取
  40. jsAPITicketCacheKey := fmt.Sprintf("%s_jsapi_ticket_%s", js.cacheKeyPrefix, js.appID)
  41. val := js.cache.Get(jsAPITicketCacheKey)
  42. if val != nil {
  43. ticketStr = val.(string)
  44. return
  45. }
  46. var ticket ResTicket
  47. ticket, err = GetTicketFromServer(accessToken)
  48. if err != nil {
  49. return
  50. }
  51. expires := ticket.ExpiresIn - 1500
  52. err = js.cache.Set(jsAPITicketCacheKey, ticket.Ticket, time.Duration(expires)*time.Second)
  53. ticketStr = ticket.Ticket
  54. return
  55. }
  56. //GetTicketFromServer 从服务器中获取ticket
  57. func GetTicketFromServer(accessToken string) (ticket ResTicket, err error) {
  58. var response []byte
  59. url := fmt.Sprintf(getTicketURL, accessToken)
  60. response, err = util.HTTPGet(url)
  61. if err != nil {
  62. return
  63. }
  64. err = json.Unmarshal(response, &ticket)
  65. if err != nil {
  66. return
  67. }
  68. if ticket.ErrCode != 0 {
  69. err = fmt.Errorf("getTicket Error : errcode=%d , errmsg=%s", ticket.ErrCode, ticket.ErrMsg)
  70. return
  71. }
  72. return
  73. }