node实现创建服务器获取wx jssdk签名

// system module
var http = require("http");
var https = require("https");
var url = require("url");
var path = require("path");
var qs = require("querystring");
var crypto = require('crypto'); // hash加密

// simple cache
var cache = require("memory-cache");

// app file
var conf = require("./config/config.js");
var route = require("./route/route.js");

http.createServer(function(req,res){
    var serverRes = res;
    var serverReq = req;
    var param = url.parse(req.url,true).query;
    var pathname = url.parse(req.url,true).pathname;
    var callback = param.callback;
    var noncestr = param.noncestr;
    var timestamp = param.timestamp;
    var needUrl = param.url;
    if(!needUrl || !noncestr || !timestamp){
        var chunk = JSON.stringify({
            errcode: 1,
            message: "参数不完整"
        });
        serverRes.end(callback+"("+chunk+")");
    }
    
    var getToken = function(){
        console.log("2.1.1");
        var data = {
            grant_type: "client_credential",
            appid: conf.wechat.AppID,
            secret: conf.wechat.AppSecret
        }
        var content = qs.stringify(data);

        var options = {
            hostname: "api.weixin.qq.com",
            port: "",
            path: "/cgi-bin/token?"+content,
            method: "GET"
        }

        var req = https.request(options,function(res){
            res.on('data', function (chunk) { 
                console.log("2.1.2");
                var statusCode = res.statusCode;
                if(statusCode != 200){
                    var chunk = JSON.stringify({
                        code: statusCode,
                        message: "获取微信token失败"
                    });
                    serverRes.end(callback+"("+chunk+")");
                }
                var chunk = JSON.parse(chunk.toString());
                cache.put("token",chunk["access_token"],7200000,function(){
                    cache.del("token");
                });
                getTicket();
            }); 
        })
        req.on("error",function(err){
            console.log(err.message); 
        })
        req.end();
    }

    var getTicket = function(){
        console.log("2.2.1");
        var data = {
            access_token: cache.get("token"),
            type: "jsapi"
        }
        var content = qs.stringify(data);
        var options = {
            hostname: "api.weixin.qq.com",
            port: "",
            path: "/cgi-bin/ticket/getticket?"+content,
            method: "GET"
        }
        var req = https.request(options,function(res){
            console.log("2.2.2");
            var statusCode = res.statusCode;
            if(statusCode != 200){
                var chunk = JSON.stringify({
                    code: statusCode,
                    message: "获取微信ticket失败"
                });
                serverRes.end(callback+"("+chunk+")");
            }
            res.on('data', function (chunk) { 
                var chunkJSON = JSON.parse(chunk.toString());
                cache.put("ticket",chunkJSON.ticket,7200000,function(){
                    cache.del("ticket");
                });
                getSingature(chunkJSON.ticket);
            }); 
        })
        req.on("error",function(err){
            console.log(err.message); 
        })
        req.end();
    }

    var getSingature = function(ticket){
        console.log(3.1);
        var data = {
            jsapi_ticket: ticket,
            noncestr: noncestr,
            timestamp: timestamp,
        };
        console.log(data);
        var content = qs.stringify(data);
        content+="&url="+needUrl;
        console.log(content);
        var shasum = crypto.createHash('sha1');
        shasum.update(content);
        var signature = shasum.digest("hex");
        console.log(signature);
        var chunk = JSON.stringify({
            errcode: 0, 
            errmsg: "ok", 
            signature: signature
        });
        serverRes.end(callback+"("+chunk+")");
    }

    /**
     * 临时先满足获取微信jsapi_ticket的需求,后续完善
     * 第一步 要想获取jsapi_ticket,首先要获取access_token(有效期7200s)
     * 第二步 通过得到的access_token,进一步获取jsapi_ticket(有效期7200s)
     * 由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,
     * 影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket
     */
    if(pathname != "/getWechatSignature"){
        res.statusCode = 404;
        res.end();
        return;
    }
    // 检测缓存中是否有jsapi_ticket,
    // 如果有这直接用此ticket获取sha1签名
    var jsapi_ticket = cache.get("ticket");
    if(jsapi_ticket && jsapi_ticket != ""){
        console.log(1);
        getSingature(jsapi_ticket);
    }else{
        /**
         * 获取 access_token
         * 如果缓存中没有token,则调用微信接口获取token
         */
        var access_token = cache.get("token");
        if(!access_token || access_token == ""){
            console.log(2.1);
            getToken();
        }else{
            console.log(2.2);
            getTicket();
        }
    }

}).listen(conf.port);

console.log((new Date()).toLocaleString() + "server start on : " + conf.host + ":" + conf.port);

 

posted @ 2016-01-21 11:07  寻一颗心  阅读(561)  评论(0编辑  收藏  举报