js.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package js
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "time"
  6. "github.com/silenceper/wechat/context"
  7. "github.com/silenceper/wechat/util"
  8. )
  9. const getTicketURL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi"
  10. //Js struct
  11. type Js struct {
  12. *context.Context
  13. }
  14. //Config 返回给用户jssdk配置信息
  15. type Config struct {
  16. AppID string
  17. TimeStamp int64
  18. NonceStr string
  19. Signature string
  20. }
  21. //resTicket 请求jsapi_tikcet返回结果
  22. type resTicket struct {
  23. util.CommonError
  24. Ticket string `json:"ticket"`
  25. ExpiresIn int64 `json:"expires_in"`
  26. }
  27. //NewJs init
  28. func NewJs(context *context.Context) *Js {
  29. js := new(Js)
  30. js.Context = context
  31. return js
  32. }
  33. //GetConfig 获取jssdk需要的配置参数
  34. //uri 为当前网页地址
  35. func (js *Js) GetConfig(uri string) (config *Config, err error) {
  36. config = new(Config)
  37. var ticketStr string
  38. ticketStr, err = js.getTicket()
  39. if err != nil {
  40. return
  41. }
  42. nonceStr := util.RandomStr(16)
  43. timestamp := util.GetCurrTs()
  44. str := fmt.Sprintf("jsapi_ticket=%s&noncestr=%s&timestamp=%d&url=%s", ticketStr, nonceStr, timestamp, uri)
  45. sigStr := util.Signature(str)
  46. config.AppID = js.AppID
  47. config.NonceStr = nonceStr
  48. config.TimeStamp = timestamp
  49. config.Signature = sigStr
  50. return
  51. }
  52. //getTicket 获取jsapi_tocket全局缓存
  53. func (js *Js) getTicket() (ticketStr string, err error) {
  54. js.GetJsApiTicketLock().Lock()
  55. defer js.GetJsApiTicketLock().Unlock()
  56. //先从cache中取
  57. jsAPITicketCacheKey := fmt.Sprintf("jsapi_ticket_%s", js.AppID)
  58. val := js.Cache.Get(jsAPITicketCacheKey)
  59. if val != nil {
  60. ticketStr = val.(string)
  61. return
  62. }
  63. var ticket resTicket
  64. ticket, err = js.getTicketFromServer()
  65. if err != nil {
  66. return
  67. }
  68. ticketStr = ticket.Ticket
  69. return
  70. }
  71. //getTicketFromServer 强制从服务器中获取ticket
  72. func (js *Js) getTicketFromServer() (ticket resTicket, err error) {
  73. var accessToken string
  74. accessToken, err = js.GetAccessToken()
  75. if err != nil {
  76. return
  77. }
  78. var response []byte
  79. url := fmt.Sprintf(getTicketURL, accessToken)
  80. response, err = util.HTTPGet(url)
  81. err = json.Unmarshal(response, &ticket)
  82. if err != nil {
  83. return
  84. }
  85. if ticket.ErrCode != 0 {
  86. err = fmt.Errorf("getTicket Error : errcode=%s , errmsg=%s", ticket.ErrCode, ticket.ErrMsg)
  87. return
  88. }
  89. jsAPITicketCacheKey := fmt.Sprintf("jsapi_ticket_%s", js.AppID)
  90. expires := ticket.ExpiresIn - 1500
  91. err = js.Cache.Set(jsAPITicketCacheKey, ticket.Ticket, time.Duration(expires)*time.Second)
  92. return
  93. }