weixin-server.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. 'use strict';
  2. const crypto = require('crypto')
  3. const {
  4. HTTP_STATUS
  5. } = require('./consts.js')
  6. const {
  7. BridgeError
  8. } = require('./bridge-error.js')
  9. class WeixinServer {
  10. constructor(options = {}) {
  11. this._appid = options.appid
  12. this._secret = options.secret
  13. }
  14. getAccessToken() {
  15. return uniCloud.httpclient.request(WeixinServer.AccessToken_Url, {
  16. dataType: 'json',
  17. method: 'POST',
  18. contentType: 'json',
  19. data: {
  20. appid: this._appid,
  21. secret: this._secret,
  22. grant_type: "client_credential"
  23. }
  24. })
  25. }
  26. // 使用客户端获取的 code 从微信服务器换取 openid,code 仅可使用一次
  27. codeToSession(code) {
  28. return uniCloud.httpclient.request(WeixinServer.Code2Session_Url, {
  29. dataType: 'json',
  30. data: {
  31. appid: this._appid,
  32. secret: this._secret,
  33. js_code: code,
  34. grant_type: 'authorization_code'
  35. }
  36. })
  37. }
  38. getUserEncryptKey({
  39. access_token,
  40. openid,
  41. session_key
  42. }) {
  43. console.log(access_token, openid, session_key);
  44. const signature = crypto.createHmac('sha256', session_key).update('').digest('hex')
  45. return uniCloud.httpclient.request(WeixinServer.User_Encrypt_Key_Url, {
  46. dataType: 'json',
  47. method: 'POST',
  48. dataAsQueryString: true,
  49. data: {
  50. access_token,
  51. openid: openid,
  52. signature: signature,
  53. sig_method: 'hmac_sha256'
  54. }
  55. })
  56. }
  57. getH5AccessToken() {
  58. return uniCloud.httpclient.request(WeixinServer.AccessToken_H5_Url, {
  59. dataType: 'json',
  60. method: 'GET',
  61. data: {
  62. appid: this._appid,
  63. secret: this._secret,
  64. grant_type: "client_credential"
  65. }
  66. })
  67. }
  68. getH5Ticket(access_token) {
  69. return uniCloud.httpclient.request(WeixinServer.Ticket_Url, {
  70. dataType: 'json',
  71. dataAsQueryString: true,
  72. method: 'POST',
  73. data: {
  74. access_token
  75. }
  76. })
  77. }
  78. getH5AccessTokenForEip() {
  79. return uniCloud.httpProxyForEip.postForm(WeixinServer.AccessToken_H5_Url, {
  80. appid: this._appid,
  81. secret: this._secret,
  82. grant_type: "client_credential"
  83. }, {
  84. dataType: 'json'
  85. })
  86. }
  87. getH5TicketForEip(access_token) {
  88. return uniCloud.httpProxyForEip.postForm(WeixinServer.Ticket_Url, {
  89. access_token
  90. }, {
  91. dataType: 'json',
  92. dataAsQueryString: true
  93. })
  94. }
  95. }
  96. WeixinServer.AccessToken_Url = 'https://api.weixin.qq.com/cgi-bin/stable_token'
  97. WeixinServer.Code2Session_Url = 'https://api.weixin.qq.com/sns/jscode2session'
  98. WeixinServer.User_Encrypt_Key_Url = 'https://api.weixin.qq.com/wxa/business/getuserencryptkey'
  99. WeixinServer.AccessToken_H5_Url = 'https://api.weixin.qq.com/cgi-bin/token'
  100. WeixinServer.Ticket_Url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi'
  101. WeixinServer.GetMPAccessToken = function(options) {
  102. return new WeixinServer(options).getAccessToken()
  103. }
  104. WeixinServer.GetCodeToSession = function(options) {
  105. return new WeixinServer(options).codeToSession(options.code)
  106. }
  107. WeixinServer.GetUserEncryptKey = function(options) {
  108. return new WeixinServer(options).getUserEncryptKey(options)
  109. }
  110. WeixinServer.GetH5AccessToken = function(options) {
  111. return new WeixinServer(options).getH5AccessToken()
  112. }
  113. WeixinServer.GetH5Ticket = function(options) {
  114. return new WeixinServer(options).getH5Ticket(options.access_token)
  115. }
  116. ////////////////////////////////////////////////////////////////
  117. function isAliyun() {
  118. return (uniCloud.getCloudInfos()[0].provider === 'aliyun')
  119. }
  120. WeixinServer.GetResponseData = function(response) {
  121. console.log("WeixinServer::response", response)
  122. if (!(response.status === HTTP_STATUS.SUCCESS || response.statusCodeValue === HTTP_STATUS.SUCCESS)) {
  123. throw new BridgeError(response.status || response.statusCodeValue, response.status || response.statusCodeValue)
  124. }
  125. const responseData = response.data || response.body
  126. if (responseData.errcode !== undefined && responseData.errcode !== 0) {
  127. throw new BridgeError(responseData.errcode, responseData.errmsg)
  128. }
  129. return responseData
  130. }
  131. WeixinServer.GetMPAccessTokenData = async function(options) {
  132. const response = await new WeixinServer(options).getAccessToken()
  133. return WeixinServer.GetResponseData(response)
  134. }
  135. WeixinServer.GetCodeToSessionData = async function(options) {
  136. const response = await new WeixinServer(options).codeToSession(options.code)
  137. return WeixinServer.GetResponseData(response)
  138. }
  139. WeixinServer.GetUserEncryptKeyData = async function(options) {
  140. const response = await new WeixinServer(options).getUserEncryptKey(options)
  141. return WeixinServer.GetResponseData(response)
  142. }
  143. WeixinServer.GetH5AccessTokenData = async function(options) {
  144. const ws = new WeixinServer(options)
  145. let response
  146. if (isAliyun()) {
  147. response = await ws.getH5AccessTokenForEip()
  148. if (typeof response === 'string') {
  149. response = JSON.parse(response)
  150. }
  151. } else {
  152. response = await ws.getH5AccessToken()
  153. }
  154. return WeixinServer.GetResponseData(response)
  155. }
  156. WeixinServer.GetH5TicketData = async function(options) {
  157. const ws = new WeixinServer(options)
  158. let response
  159. if (isAliyun()) {
  160. response = await ws.getH5TicketForEip(options.access_token)
  161. if (typeof response === 'string') {
  162. response = JSON.parse(response)
  163. }
  164. } else {
  165. response = await ws.getH5Ticket(options.access_token)
  166. }
  167. return WeixinServer.GetResponseData(response)
  168. }
  169. module.exports = {
  170. WeixinServer
  171. }