|
@@ -0,0 +1,180 @@
|
|
|
+
|
|
|
+ * @Author HonorLee (deve@honorlee.me)
|
|
|
+ * @Version 1.0 (2018-05-05)
|
|
|
+ * @License MIT
|
|
|
+ */
|
|
|
+'use strict'
|
|
|
+const sha1 = require('sha1');
|
|
|
+const tmpTokenFile = Core.Path.Temp + '/wechat_AccessToken.txt';
|
|
|
+const tmpTicketFile = Core.Path.Temp + '/wechat_JsApiTicket.txt';
|
|
|
+const WechatDomain = `https://${Config.Wechat.apiDomain}`;
|
|
|
+const errCode = require('./errMsg.js');
|
|
|
+const WechatApiURL = {
|
|
|
+ getAccessToken:`${WechatDomain}/cgi-bin/token?grant_type=client_credential&appid=${Config.Wechat.appId}&secret=${Config.Wechat.appSecret}`,
|
|
|
+ getJsApiTicket:`${WechatDomain}/cgi-bin/ticket/getticket?type=jsapi&access_token=`
|
|
|
+}
|
|
|
+
|
|
|
+let Wechat = {
|
|
|
+ checkSignature:function(signature,timestamp,nonce){
|
|
|
+ let arr = [Config.Wechat.token, timestamp, nonce];
|
|
|
+ arr.sort();
|
|
|
+ let content = arr.join('');
|
|
|
+ return sha1(content) === signature;
|
|
|
+ },
|
|
|
+ getAccessToken:function(callback){
|
|
|
+ let _this = this;
|
|
|
+ getTokenFromCache(function(data){
|
|
|
+ if(data){
|
|
|
+ callback.call(_this,null,data);
|
|
|
+ }else{
|
|
|
+ Core.Request({url:WechatApiURL.getAccessToken,encoding:'UTF-8',json:true},function(err,response,body){
|
|
|
+ if(err || !body){
|
|
|
+ Logger.error('Wechat getAccessToken error!');
|
|
|
+ Logger.error(err);
|
|
|
+ callback.call(_this,new Error('Wechat getAccessToken error!'),null);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if(body.errcode){
|
|
|
+ callback(_this,errcode,errcode[body.errcode]);
|
|
|
+ }
|
|
|
+ let token = body.access_token;
|
|
|
+ let expires = body.expires_in;
|
|
|
+ setTokenToCahe(token,expires);
|
|
|
+ callback.call(_this,null,token);
|
|
|
+ })
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getJsApiTicket:function(callback){
|
|
|
+ let _this = this;
|
|
|
+ Wechat.getAccessToken(function(err,token){
|
|
|
+ if(!err){
|
|
|
+ getTicketFromCache(function(data){
|
|
|
+ if(data){
|
|
|
+ callback.call(_this,null,data);
|
|
|
+ }else{
|
|
|
+ let url = WechatApiURL.getJsApiTicket + token;
|
|
|
+ Core.Request({url:url,encoding:'UTF-8',json:true},function(err,response,body){
|
|
|
+ if(err || !body){
|
|
|
+ Logger.error('Wechat getJsApiTicket error!');
|
|
|
+ Logger.error(err);
|
|
|
+ callback.call(_this,new Error('Wechat getJsApiTicket error!'),null);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ console.log(body);
|
|
|
+ if(body.errcode){
|
|
|
+ callback(_this,errcode,errcode[body.errcode]);
|
|
|
+ }
|
|
|
+ let ticket = body.ticket;
|
|
|
+ let expires = body.expires_in;
|
|
|
+ setTicketToCahe(ticket,expires);
|
|
|
+ callback.call(_this,null,ticket);
|
|
|
+ })
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }else{
|
|
|
+ Logger.error('Wechat getJsApiTicket error!');
|
|
|
+ Logger.error(err);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getSignature:function(url,callback){
|
|
|
+ if(!url) return callback.call(this,new Error('URL is empty!'),null);
|
|
|
+ let _this = this;
|
|
|
+ let noncestr = String.random(16);
|
|
|
+ let timestamp = Math.floor(Moment().valueOf()/1000);
|
|
|
+ Wechat.getJsApiTicket(function(err,ticket){
|
|
|
+ if(err){
|
|
|
+ Logger.error('Wechat getSignature error!');
|
|
|
+ Logger.error(err);
|
|
|
+ callback.call(_this,err,null);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let combineStr = `jsapi_ticket=${ticket}&noncestr=${noncestr}×tamp=${timestamp}&url=${url}`;
|
|
|
+ let signature = sha1(combineStr);
|
|
|
+ callback.call(_this,null,{noncestr:noncestr,timestamp:timestamp,signature:signature});
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+module.exports = Wechat;
|
|
|
+
|
|
|
+function getTokenFromCache(callback){
|
|
|
+ if(Config.Wechat.StoreType=='Memcache'){
|
|
|
+ Memcache.get('wechat_AccessToken',function(err,data){
|
|
|
+ if(!err && data){
|
|
|
+ callback(data);
|
|
|
+ }else{
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try{
|
|
|
+ FILE.statSync(tmpTokenFile);
|
|
|
+ }catch(e){
|
|
|
+ callback(null);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let obj = JSON.parse(FILE.readFileSync(tmpTokenFile,'UTF-8'));
|
|
|
+ let now = Math.floor(Moment().valueOf()/1000)+60;
|
|
|
+ if(now < obj.expires){
|
|
|
+ callback(obj.token);
|
|
|
+ }else{
|
|
|
+ callback(null);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+function setTokenToCahe(token,expires){
|
|
|
+ expires = expires - 60;
|
|
|
+ if(Config.Wechat.StoreType=='Memcache'){
|
|
|
+ Memcache.set('wechat_AccessToken',token,expires,function(err){
|
|
|
+ if(err) console.log(err);
|
|
|
+ })
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let expiresTime = Moment().valueOf() + expires;
|
|
|
+ FILE.writeFileSync(tmpTokenFile,JSON.stringify({token:token,expires:expiresTime}),'UTF-8');
|
|
|
+}
|
|
|
+
|
|
|
+function getTicketFromCache(callback){
|
|
|
+ if(Config.Wechat.StoreType=='Memcache'){
|
|
|
+ Memcache.get('wechat_JsApiTicket',function(err,data){
|
|
|
+ if(!err && data){
|
|
|
+ callback(data);
|
|
|
+ }else{
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try{
|
|
|
+ FILE.statSync(tmpTicketFile);
|
|
|
+ }catch(e){
|
|
|
+ callback(null);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let obj = JSON.parse(FILE.readFileSync(tmpTicketFile,'UTF-8'));
|
|
|
+ let now = Math.floor(Moment().valueOf()/1000)+60;
|
|
|
+ if(now < obj.expires){
|
|
|
+ callback(obj.ticket);
|
|
|
+ }else{
|
|
|
+ callback(null);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+function setTicketToCahe(ticket,expires){
|
|
|
+ expires = expires - 5;
|
|
|
+ if(Config.Wechat.StoreType=='Memcache'){
|
|
|
+ Memcache.set('wechat_JsApiTicket',ticket,expires,function(err){
|
|
|
+ if(err) console.log(err);
|
|
|
+ })
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let expiresTime = Moment().valueOf() + expires;
|
|
|
+ FILE.writeFileSync(tmpTicketFile,JSON.stringify({ticket:ticket,expires:expiresTime}),'UTF-8');
|
|
|
+}
|