第一步:根据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+\'×tamp=\' + 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 + \'×tamp=\' + 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");
});