|  | @@ -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');
 | 
	
		
			
				|  |  | +}
 |