wechat.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /**
  2. * @Author HonorLee (deve@honorlee.me)
  3. * @Version 1.0 (2018-05-05)
  4. * @License MIT
  5. */
  6. 'use strict'
  7. const sha1 = require('sha1');
  8. const tmpTokenFile = Core.Path.Temp + '/wechat_AccessToken.txt';
  9. const tmpTicketFile = Core.Path.Temp + '/wechat_JsApiTicket.txt';
  10. const WechatDomain = `https://${Config.Wechat.apiDomain}`;
  11. const errCode = require('./errMsg.js');
  12. const WechatApiURL = {
  13. getAccessToken:`${WechatDomain}/cgi-bin/token?grant_type=client_credential&appid=${Config.Wechat.appId}&secret=${Config.Wechat.appSecret}`,
  14. getJsApiTicket:`${WechatDomain}/cgi-bin/ticket/getticket?type=jsapi&access_token=`
  15. }
  16. let Wechat = {
  17. checkSignature:function(signature,timestamp,nonce){
  18. let arr = [Config.Wechat.token, timestamp, nonce];
  19. arr.sort();
  20. let content = arr.join('');
  21. return sha1(content) === signature;
  22. },
  23. getAccessToken:function(callback){
  24. let _this = this;
  25. getTokenFromCache(function(data){
  26. if(data){
  27. callback.call(_this,null,data);
  28. }else{
  29. Core.Request({url:WechatApiURL.getAccessToken,encoding:'UTF-8',json:true},function(err,response,body){
  30. if(err || !body){
  31. Logger.error('Wechat getAccessToken error!');
  32. Logger.error(err);
  33. callback.call(_this,new Error('Wechat getAccessToken error!'),null);
  34. return;
  35. }
  36. if(body.errcode){
  37. callback(_this,errcode,errcode[body.errcode]);
  38. }
  39. let token = body.access_token;
  40. let expires = body.expires_in;
  41. setTokenToCahe(token,expires);
  42. callback.call(_this,null,token);
  43. })
  44. }
  45. });
  46. },
  47. getJsApiTicket:function(callback){
  48. let _this = this;
  49. Wechat.getAccessToken(function(err,token){
  50. if(!err){
  51. getTicketFromCache(function(data){
  52. if(data){
  53. callback.call(_this,null,data);
  54. }else{
  55. let url = WechatApiURL.getJsApiTicket + token;
  56. Core.Request({url:url,encoding:'UTF-8',json:true},function(err,response,body){
  57. if(err || !body){
  58. Logger.error('Wechat getJsApiTicket error!');
  59. Logger.error(err);
  60. callback.call(_this,new Error('Wechat getJsApiTicket error!'),null);
  61. return;
  62. }
  63. console.log(body);
  64. if(body.errcode){
  65. callback(_this,errcode,errcode[body.errcode]);
  66. }
  67. let ticket = body.ticket;
  68. let expires = body.expires_in;
  69. setTicketToCahe(ticket,expires);
  70. callback.call(_this,null,ticket);
  71. })
  72. }
  73. });
  74. }else{
  75. Logger.error('Wechat getJsApiTicket error!');
  76. Logger.error(err);
  77. }
  78. });
  79. },
  80. getSignature:function(url,callback){
  81. if(!url) return callback.call(this,new Error('URL is empty!'),null);
  82. let _this = this;
  83. let noncestr = String.random(16);
  84. let timestamp = Math.floor(Moment().valueOf()/1000);
  85. Wechat.getJsApiTicket(function(err,ticket){
  86. if(err){
  87. Logger.error('Wechat getSignature error!');
  88. Logger.error(err);
  89. callback.call(_this,err,null);
  90. return;
  91. }
  92. let combineStr = `jsapi_ticket=${ticket}&noncestr=${noncestr}&timestamp=${timestamp}&url=${url}`;
  93. let signature = sha1(combineStr);
  94. callback.call(_this,null,{noncestr:noncestr,timestamp:timestamp,signature:signature});
  95. });
  96. }
  97. }
  98. module.exports = Wechat;
  99. function getTokenFromCache(callback){
  100. if(Config.Wechat.StoreType=='Memcache' && Config.Database.Memcache.on){
  101. Memcache.get('wechat_AccessToken',function(err,data){
  102. if(!err && data){
  103. callback(data);
  104. }else{
  105. callback();
  106. }
  107. });
  108. return;
  109. }
  110. try{
  111. FILE.statSync(tmpTokenFile);
  112. }catch(e){
  113. callback(null);
  114. return;
  115. }
  116. let obj = JSON.parse(FILE.readFileSync(tmpTokenFile,'UTF-8'));
  117. let now = Math.floor(Moment().valueOf()/1000)+60;
  118. if(now < obj.expires){
  119. callback(obj.token);
  120. }else{
  121. callback(null);
  122. }
  123. }
  124. function setTokenToCahe(token,expires){
  125. expires = expires - 60;
  126. if(Config.Wechat.StoreType=='Memcache' && Config.Database.Memcache.on){
  127. Memcache.set('wechat_AccessToken',token,expires,function(err){
  128. if(err) console.log(err);
  129. })
  130. return;
  131. }
  132. let expiresTime = Moment().valueOf() + expires;
  133. FILE.writeFileSync(tmpTokenFile,JSON.stringify({token:token,expires:expiresTime}),'UTF-8');
  134. }
  135. function getTicketFromCache(callback){
  136. if(Config.Wechat.StoreType=='Memcache' && Config.Database.Memcache.on){
  137. Memcache.get('wechat_JsApiTicket',function(err,data){
  138. if(!err && data){
  139. callback(data);
  140. }else{
  141. callback();
  142. }
  143. });
  144. return;
  145. }
  146. try{
  147. FILE.statSync(tmpTicketFile);
  148. }catch(e){
  149. callback(null);
  150. return;
  151. }
  152. let obj = JSON.parse(FILE.readFileSync(tmpTicketFile,'UTF-8'));
  153. let now = Math.floor(Moment().valueOf()/1000)+60;
  154. if(now < obj.expires){
  155. callback(obj.ticket);
  156. }else{
  157. callback(null);
  158. }
  159. }
  160. function setTicketToCahe(ticket,expires){
  161. expires = expires - 5;
  162. if(Config.Wechat.StoreType=='Memcache' && Config.Database.Memcache.on){
  163. Memcache.set('wechat_JsApiTicket',ticket,expires,function(err){
  164. if(err) console.log(err);
  165. })
  166. return;
  167. }
  168. let expiresTime = Moment().valueOf() + expires;
  169. FILE.writeFileSync(tmpTicketFile,JSON.stringify({ticket:ticket,expires:expiresTime}),'UTF-8');
  170. }