123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- /**
- * @Author HonorLee (dev@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 errMsg = 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=`,
- getJsOauthCode:`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${Config.Wechat.appId}`,
- getOauthToken:`${WechatDomain}/sns/oauth2/access_token?appid=${Config.Wechat.appId}&secret=${Config.Wechat.appSecret}&grant_type=authorization_code`,
- getOauthUserinfo:`${WechatDomain}/sns/userinfo?lang=zh_CN`
- }
- 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,body.errcode,errMsg[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;
- }
- if(body.errcode){
- callback(_this,body.errcode,errMsg[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});
- });
- },
- getJsOauthCodeURL:function(redirectURL,Scope,State){
- if(!redirectURL || !redirectURL.match(/(https?):\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/gi)){
- return {err:'redirectURL Error'};
- }
- if(Scope!='snsapi_base' && Scope!='snsapi_userinfo'){
- return {err:'Scope must be snsapi_base or snsapi_userinfo'};
- }
- if(!State) State = 'null';
- redirectURL = encodeURI(redirectURL);
- let urlString = WechatApiURL.getJsOauthCode + `&redirect_uri=${redirectURL}&response_type=code&scope=${Scope}&state=${State}#wechat_redirect`;
- return {err:'',url:urlString};
- },
- getOauthToken:function(code,callback){
- if(!code) return callback.call(this,new Error('Code is empty!'),null);
- let _this = this;
- let url = WechatApiURL.getOauthToken + `&code=${code}`;
- Core.Request({url:url,encoding:'UTF-8',json:true},function(err,response,body){
- if(err || !body){
- Logger.error('Wechat getOauthToken error!');
- Logger.error(err);
- callback.call(_this,new Error('Wechat getOauthToken error!'),null);
- return;
- }
- if(body.errcode){
- return callback.call(_this,body.errcode,errMsg[body.errcode]);
- }
- callback.call(_this,null,body);
- });
- },
- getOauthUserinfo:function(access_token,openid,callback){
- let _this = this;
- if(!access_token) return callback.call(this,new Error('access_token is empty'));
- if(!openid) return callback.call(this,new Error('openid is empty'));
- let url = WechatApiURL.getOauthUserinfo + `&access_token=${access_token}&openid=${openid}`;
- Core.Request({url:url,encoding:'UTF-8',json:true},function(err,response,body){
- if(err || !body){
- Logger.error('Wechat getOauthUserinfo error!');
- Logger.error(err);
- callback.call(_this,new Error('Wechat getOauthUserinfo error!'),null);
- return;
- }
- if(body.errcode){
- return callback.call(_this,body.errcode,errMsg[body.errcode]);
- }
- callback.call(_this,null,body);
- });
- },
- getOauthUserinfoByCode:function(code,callback){
- if(!code) return callback.call(this,new Error('Code is empty!'),null);
- let _this = this;
- Wechat.getOauthToken(code,function(err,result){
- if(err) return callback.call(_this,err,null);
- Wechat.getOauthUserinfo(result.access_token,result.openid,function(err,result){
- if(err) return callback.call(_this,err,null);
- callback.call(_this,null,result);
- });
- });
- }
- }
- module.exports = Wechat;
- function getTokenFromCache(callback){
- if(Config.Wechat.StoreType=='Memcache' && Config.Database.Memcache.on){
- 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' && Config.Database.Memcache.on){
- Memcache.set('wechat_AccessToken',token,expires,function(err){
- if(err) console.log(err);
- })
- return;
- }
- let expiresTime = Math.floor(Moment().valueOf()/1000) + expires;
- FILE.writeFileSync(tmpTokenFile,JSON.stringify({token:token,expires:expiresTime}),'UTF-8');
- }
- function getTicketFromCache(callback){
- if(Config.Wechat.StoreType=='Memcache' && Config.Database.Memcache.on){
- 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' && Config.Database.Memcache.on){
- Memcache.set('wechat_JsApiTicket',ticket,expires,function(err){
- if(err) console.log(err);
- })
- return;
- }
- let expiresTime = Math.floor(Moment().valueOf()/1000) + expires;
- FILE.writeFileSync(tmpTicketFile,JSON.stringify({ticket:ticket,expires:expiresTime}),'UTF-8');
- }
|