附近小店
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

auth.go 6.1 KiB

3 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. package weapp
  2. import (
  3. "applet/app/cfg"
  4. "applet/app/utils"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "github.com/tidwall/gjson"
  9. )
  10. const (
  11. apiLogin = "/sns/jscode2session"
  12. apiGetAccessToken = "/cgi-bin/token"
  13. apiGetPaidUnionID = "/wxa/getpaidunionid"
  14. apiQetticket = "/cgi-bin/ticket/getticket"
  15. apiLoginWebsiteBackend = "/Wx/getJsCode2session"
  16. )
  17. // LoginResponse 返回给用户的数据
  18. type LoginResponse struct {
  19. CommonError
  20. OpenID string `json:"openid"`
  21. SessionKey string `json:"session_key"`
  22. // 用户在开放平台的唯一标识符
  23. // 只在满足一定条件的情况下返回
  24. UnionID string `json:"unionid"`
  25. }
  26. // Login 登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。
  27. //
  28. // appID 小程序 appID
  29. // secret 小程序的 app secret
  30. // code 小程序登录时获取的 code
  31. func Login(appID, secret, code string) (*LoginResponse, error) {
  32. api := baseURL + apiLogin
  33. return login(appID, secret, code, api)
  34. }
  35. // 调用总站长后台的接口
  36. func LoginForWebsiteBackend(uid string, appID, code string) (*LoginResponse, error) {
  37. utils.FilePutContents("o2o_wechat_mini", "appId :"+appID+", code: "+code)
  38. api := cfg.WebsiteBackend.URL + apiLoginWebsiteBackend + "?appid=" + appID + "&js_code=" + code + "&uid=" + uid
  39. //res := new(LoginResponse)
  40. resByte, err := utils.CurlGet(api, nil)
  41. if err != nil {
  42. utils.FilePutContents("o2o_wechat_mini", "url:"+api)
  43. return nil, err
  44. }
  45. fmt.Println(api, string(resByte), err)
  46. var data struct {
  47. Code int `json:"code"`
  48. Msg string `json:"msg"`
  49. Data LoginResponse `json:"data"`
  50. }
  51. if gjson.Get(string(resByte), "code").Int() > 0 {
  52. return nil, errors.New(gjson.Get(string(resByte), "msg").String())
  53. }
  54. err = json.Unmarshal(resByte, &data)
  55. if err != nil {
  56. utils.FilePutContents("o2o_wechat_mini", "err:"+err.Error()+"res: "+string(resByte))
  57. return nil, err
  58. }
  59. if data.Code != 0 {
  60. return nil, errors.New(data.Msg)
  61. }
  62. //if err := getJSON(api, res); err != nil {
  63. // utils.FilePutContents("o2o_wechat_mini", "url:"+api)
  64. // return nil, err
  65. //}
  66. utils.FilePutContents("o2o_wechat_mini", string(resByte))
  67. return &data.Data, nil
  68. }
  69. func login(appID, secret, code, api string) (*LoginResponse, error) {
  70. queries := requestQueries{
  71. "appid": appID,
  72. "secret": secret,
  73. "js_code": code,
  74. "grant_type": "authorization_code",
  75. }
  76. url, err := encodeURL(api, queries)
  77. if err != nil {
  78. return nil, err
  79. }
  80. res := new(LoginResponse)
  81. if err := getJSON(url, res); err != nil {
  82. return nil, err
  83. }
  84. return res, nil
  85. }
  86. // TokenResponse 获取 access_token 成功返回数据
  87. type TokenResponse struct {
  88. CommonError
  89. AccessToken string `json:"access_token"` // 获取到的凭证
  90. ExpiresIn uint `json:"expires_in"` // 凭证有效时间,单位:秒。目前是7200秒之内的值。
  91. }
  92. // GetAccessToken 获取小程序全局唯一后台接口调用凭据(access_token)。
  93. // 调调用绝大多数后台接口时都需使用 access_token,开发者需要进行妥善保存,注意缓存。
  94. func GetAccessToken(appID, secret string) (*TokenResponse, error) {
  95. api := baseURL + apiGetAccessToken
  96. return getAccessToken(appID, secret, api)
  97. }
  98. func getAccessToken(appID, secret, api string) (*TokenResponse, error) {
  99. queries := requestQueries{
  100. "appid": appID,
  101. "secret": secret,
  102. "grant_type": "client_credential",
  103. }
  104. url, err := encodeURL(api, queries)
  105. if err != nil {
  106. return nil, err
  107. }
  108. res := new(TokenResponse)
  109. if err := getJSON(url, res); err != nil {
  110. return nil, err
  111. }
  112. return res, nil
  113. }
  114. // TicketResponse 获取 Ticket 成功返回数据
  115. type TicketResponse struct {
  116. CommonError
  117. ExpiresIn uint `json:"expires_in"` // 凭证有效时间,单位:秒。目前是7200秒之内的值。
  118. Errcode int `json:"errcode"`
  119. Ticket string `json:"ticket"`
  120. }
  121. func Getticket(appID, access_token string) (*TicketResponse, error) {
  122. api := baseURL + apiQetticket
  123. return getticket(appID, access_token, api)
  124. }
  125. func getticket(appID, access_token, api string) (*TicketResponse, error) {
  126. queries := requestQueries{
  127. "access_token": access_token,
  128. "type": "jsapi",
  129. }
  130. url, err := encodeURL(api, queries)
  131. if err != nil {
  132. return nil, err
  133. }
  134. res := new(TicketResponse)
  135. fmt.Println(res, "res")
  136. fmt.Println(access_token, "access_token")
  137. if err := getJSON(url, res); err != nil {
  138. return nil, err
  139. }
  140. return res, nil
  141. }
  142. // GetPaidUnionIDResponse response data
  143. type GetPaidUnionIDResponse struct {
  144. CommonError
  145. UnionID string `json:"unionid"`
  146. }
  147. // GetPaidUnionID 用户支付完成后,通过微信支付订单号(transaction_id)获取该用户的 UnionId,
  148. func GetPaidUnionID(accessToken, openID, transactionID string) (*GetPaidUnionIDResponse, error) {
  149. api := baseURL + apiGetPaidUnionID
  150. return getPaidUnionID(accessToken, openID, transactionID, api)
  151. }
  152. func getPaidUnionID(accessToken, openID, transactionID, api string) (*GetPaidUnionIDResponse, error) {
  153. queries := requestQueries{
  154. "openid": openID,
  155. "access_token": accessToken,
  156. "transaction_id": transactionID,
  157. }
  158. return getPaidUnionIDRequest(api, queries)
  159. }
  160. // GetPaidUnionIDWithMCH 用户支付完成后,通过微信支付商户订单号和微信支付商户号(out_trade_no 及 mch_id)获取该用户的 UnionId,
  161. func GetPaidUnionIDWithMCH(accessToken, openID, outTradeNo, mchID string) (*GetPaidUnionIDResponse, error) {
  162. api := baseURL + apiGetPaidUnionID
  163. return getPaidUnionIDWithMCH(accessToken, openID, outTradeNo, mchID, api)
  164. }
  165. func getPaidUnionIDWithMCH(accessToken, openID, outTradeNo, mchID, api string) (*GetPaidUnionIDResponse, error) {
  166. queries := requestQueries{
  167. "openid": openID,
  168. "mch_id": mchID,
  169. "out_trade_no": outTradeNo,
  170. "access_token": accessToken,
  171. }
  172. return getPaidUnionIDRequest(api, queries)
  173. }
  174. func getPaidUnionIDRequest(api string, queries requestQueries) (*GetPaidUnionIDResponse, error) {
  175. url, err := encodeURL(api, queries)
  176. if err != nil {
  177. return nil, err
  178. }
  179. res := new(GetPaidUnionIDResponse)
  180. if err := getJSON(url, res); err != nil {
  181. return nil, err
  182. }
  183. return res, nil
  184. }