第一步:根据corpid和secret去微信接口'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=' + config.appId + '&corpsecret=' + config.appSecret;这里拿到access_token,

access_token有时间限制,先把它存在文件或数据库里 ,到期就自动再重新获取一次,再通过access_token去拿取ticket,接着再用算法生成签名给到前台拿去与微信接口做配置。

 

var url = require('url');
var crypto = require('crypto');
var request = require('request');
var async = require('async');
var BufferHelp = require('bufferhelper');
var iconv = require('iconv-lite');
var fs = require('fs');


var cache = {
    ticket: null,
    time: 0
};

function getSignature(config, url, cb) {
    console.log('start getSignature');
    // 判断内存中是否有缓存
    if (!cache || !cache.ticket) {
        console.log('readCache');
        readFile('cache.json', function(str) {
            if (str) {
                console.log(str);
                cache = JSON.parse(str);
            }
            tryGetSignature(config, url, cb);
        });
    }
    else {
        tryGetSignature(config, url, cb);
    }
}

function checkSignature(config) {
    return function(req, res, next) {
        console.log('checkSignature');
        req.query = url.parse(req.url, true).query;

        if (req.query.getsignature) {
            console.log('req.query.getsignature');
            return next();
        }


        if (!req.query.signature) {
            return res.end('Access Denied!');
        }
        var tmp = [config.appToken, req.query.timestamp, req.query.nonce].sort().join('');
        var signature = crypto.createHash('sha1').update(tmp).digest('hex');
        if (req.query.signature != signature) {
            console.log('req.query.signature != signature');
            return res.end('Auth failed!'); // 指纹码不匹配时返回错误信息,禁止后面的消息接受及发送
        }
        if (req.query.echostr) {
            console.log('req.query.echostr');
            return res.end(req.query.echostr); // 添加公众号接口地址时,返回查询字符串echostr表示验证通过
        }
        // 消息真实性验证通过,继续后面的处理
        return next();
    };
}


function getToken(config, cb) {
    //var tokenUrl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appId=' + config.appId + '&secret=' + config.appSecret;
    var tokenUrl = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=' + config.appId + '&corpsecret=' + config.appSecret;

    request.get(tokenUrl, function(error, response, body) {
        if (error) {
            cb('getToken error', error);
        }
        else {
            try {
                console.log(body);
                var token = JSON.parse(body).access_token;
                var tt ={
                    token:token
                };
                writeFile('token.json', JSON.stringify(tt));
                cb(null, token);
            }
            catch (e) {
                cb('getToken error', e);
            }
        }
    });
}

function getNewTicket(token, cb) {
    //https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN
    //request.get('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + token + '&type=jsapi', function(error, res, body) {
    request.get('https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=' + token , function(error, res, body) {
        if (error) {
            cb('getNewTicket error', error);
        }
        else {
            try {
                console.log(JSON.parse(body));
                var ticket = JSON.parse(body).ticket;
                cb(null, ticket);
            }
            catch (e) {
                cb('getNewTicket error', e);
            }
        }
    });
}



function tryGetSignature(config, u, cb) {
    // 判断cache 是否过期
    if (!cache.ticket || (new Date().getTime() - cache.time) > 7000000) {
        async.waterfall([function(cb) {
            console.log('start getNew Ticket', cache);
            getToken(config, cb);
        }, function(token, cb) {
            getNewTicket(token, cb);
        }], function(error, result) {
            if (error) {
                cb('getToken getNewTicket error', error);
            }
            else {
                cache.ticket = result;
                cache.time = new Date().getTime();
                // 文件保存
                writeFile('cache.json', JSON.stringify(cache));
                console.log(result);

                var timestamp = getTimesTamp();
                var noncestr = getNonceStr();
                var str = 'jsapi_ticket=' + result + '&noncestr='+ noncestr+'&timestamp=' + timestamp + '&url=' + u;
                console.log(str);
                var signature = crypto.createHash('sha1').update(str).digest('hex');
                cb(null, {
                    appId: config.appId,
                    timestamp: timestamp,
                    nonceStr: noncestr,
                    signature: signature
                });
            }
        });
    }
    else {
        console.log('缓存获取');
        var timestamp = getTimesTamp();
        var noncestr = getNonceStr();
        var str = 'jsapi_ticket=' + cache.ticket + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + u;
        console.log(str);
        var signature = crypto.createHash('sha1').update(str).digest('hex');
        cb(null, {
            appId: config.appId,
            timestamp: timestamp,
            nonceStr: noncestr,
            signature: signature
        });
    }
}

function getTimesTamp() {
    return parseInt(new Date().getTime() / 1000) + '';
}

function getNonceStr() {
    return Math.random().toString(36).substr(2, 15);
}


function readFile(path, cb) {
    var readstream = fs.createReadStream(path);
    var bf = new BufferHelp();
    readstream.on('data', function(chunk) {
        bf.concat(chunk);
    });
    readstream.on('end', function() {
        cb && cb(decodeBuffer(bf));
    });
}

function writeFile(path, str, cb) {
    var writestream = fs.createWriteStream(path);

    writestream.write(str);
    writestream.on('close', function() {
        cb && cb();
    });
}

function decodeBuffer(bf, encoding) {
    var val = iconv.decode(bf.toBuffer(), encoding || 'utf8');
    if (val.indexOf('�') != -1) {
        val = iconv.decode(bf.toBuffer(), 'gbk');
    }
    return val;
}

exports.checkSignature = checkSignature;
exports.getSignature = function(config) {
    return function(url, cb) {
        getSignature(config, url, cb);
    }
};
var signature = require('../signature');
var config = require('../config')();
var express = require('express');

var createSignature = signature.getSignature(config);
//var express = require('express');
var WXBizMsgCrypt = require('wechat-crypto');

var configN = {
    token: 'shangmenxia',
    encodingAESKey: 'kgIgMwv8Uf7dOPTEFyYIPIzk5D3W9s9havZymNgr33U',
    corpId: 'wx3cc22c4e7a4d4312'
};
module.exports = function(app) {
    app.post('/getsignature', getSignature);
    app.get('/test', fun);
    app.get('/wxservice', function(req, res){
        var msg_signature = req.query.msg_signature;
        var timestamp = req.query.timestamp;
        var nonce = req.query.nonce;
        var echostr = req.query.echostr;
        var cryptor = new WXBizMsgCrypt(configN.token, configN.encodingAESKey, configN.corpId);
        var s = cryptor.decrypt(echostr);
        res.send(s.message);
    });
};

function fun(req, res) {
    var u = req.protocol + "://" + req.get('Host') + req.url;
    createSignature(u, function(error, result) {
        console.log(result);
        res.render('../public/html/login.html', result);
    });
}

function getSignature(req, res) {
    var url = req.body.url;
    console.log(url);
    createSignature(url, function(error, result) {
        if (error) {
            res.json({
                'error': error
            });
        } else {
            res.json(result);
        }
    });
}

  //app.js  运行文件

var express = require('express'),
    routes = require('./routes/routes'),
    http = require('http'),
    path = require('path');
var template = require('art-template');
var app = express();
app.use(express.static(__dirname+"/public"));
app.configure(function() {
    app.set('port', process.env.PORT || 1342);
    template.config('base', '');
    template.config('extname', '.html');
    app.engine('.html', template.__express);
    app.set('view engine', 'html');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.static(path.join(__dirname, 'public')));

    // user
    // 这是用来 在接口配置信息 中验证的; 仅仅使用 JS-SDK 不需要使用;
    // app.use(signature.checkSignature(config));
});

app.configure('development', function() {
    app.use(express.errorHandler());
});
routes(app);
http.createServer(app).listen(9001, function() {
    console.log("企业号监听 9001");
});

  

 

posted on 2016-05-27 16:37  低调活,高调唱  阅读(485)  评论(0编辑  收藏  举报