js.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package js
  2. import (
  3. context2 "context"
  4. "fmt"
  5. "github.com/silenceper/wechat/v2/credential"
  6. "github.com/silenceper/wechat/v2/officialaccount/context"
  7. officialJs "github.com/silenceper/wechat/v2/officialaccount/js"
  8. "github.com/silenceper/wechat/v2/util"
  9. )
  10. // Js wx jssdk
  11. type Js struct {
  12. *context.Context
  13. credential.JsTicketHandle
  14. }
  15. // NewJs init
  16. func NewJs(context *context.Context, appID string) *Js {
  17. js := new(Js)
  18. js.Context = context
  19. jsTicketHandle := credential.NewDefaultJsTicket(appID, credential.CacheKeyOfficialAccountPrefix, context.Cache)
  20. js.SetJsTicketHandle(jsTicketHandle)
  21. return js
  22. }
  23. // SetJsTicketHandle 自定义js ticket取值方式
  24. func (js *Js) SetJsTicketHandle(ticketHandle credential.JsTicketHandle) {
  25. js.JsTicketHandle = ticketHandle
  26. }
  27. // GetConfig 第三方平台 - 获取jssdk需要的配置参数
  28. // uri 为当前网页地址
  29. func (js *Js) GetConfig(uri, appid string) (config *officialJs.Config, err error) {
  30. return js.GetConfigContext(context2.Background(), uri, appid)
  31. }
  32. // GetConfigContext 新方法,允许传入上下文,避免协程泄漏
  33. func (js *Js) GetConfigContext(ctx context2.Context, uri, appid string) (config *officialJs.Config, err error) {
  34. var accessToken string
  35. // 类型断言,如果断言成功,调用安全的 GetAccessTokenContext 方法
  36. if ctxHandle, ok := js.Context.AccessTokenHandle.(credential.AccessTokenContextHandle); ok {
  37. accessToken, err = ctxHandle.GetAccessTokenContext(ctx)
  38. } else {
  39. // 如果没有实现 AccessTokenContextHandle 接口,调用旧的 GetAccessToken 方法
  40. accessToken, err = js.Context.GetAccessToken()
  41. }
  42. if err != nil {
  43. return
  44. }
  45. var ticketStr string
  46. // 类型断言 jsTicket
  47. if ticketCtxHandle, ok := js.JsTicketHandle.(credential.JsTicketContextHandle); ok {
  48. ticketStr, err = ticketCtxHandle.GetTicketContext(ctx, accessToken)
  49. } else {
  50. // 如果没有实现 JsTicketContextHandle 接口,调用旧的 GetTicket 方法
  51. ticketStr, err = js.GetTicket(accessToken)
  52. }
  53. if err != nil {
  54. return
  55. }
  56. nonceStr := util.RandomStr(16)
  57. timestamp := util.GetCurrTS()
  58. str := fmt.Sprintf("jsapi_ticket=%s&noncestr=%s&timestamp=%d&url=%s", ticketStr, nonceStr, timestamp, uri)
  59. sigStr := util.Signature(str)
  60. config = new(officialJs.Config)
  61. config.AppID = appid
  62. config.NonceStr = nonceStr
  63. config.Timestamp = timestamp
  64. config.Signature = sigStr
  65. return
  66. }