NodeJS实现微信协议登录

//使用NodeJs实现微信协议登录
var http = require('http');
var https = require("https");
var crypto = require('crypto');
var fs = require('fs');
var express = require('express');
var iconv = require("iconv-lite");
var bodyParser = require("body-parser");
var app = express();
var request = require('request');
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

function getSubstr(ret,start,end)
{
    var deps = ret.indexOf(start)+start.length;
    //如果结束字符为空,则取从开始字符到结束字符的所有字符串
    if (end == "")
    var depe = ret.length;
    else
    var depe = ret.indexOf(end);
    var dep = ret.substr(deps,depe-deps);
    return dep;
}
function rand(Min,Max){
      var Range = Max - Min;
      var Rand = Math.random();
      var num = Min + Math.round(Rand * Range); //四舍五入
      return num;
}
function getTimeStamps(){
    return Date.parse(new Date())/1000;
}

function debug(msg) {
    console.log("Console\t" + getTime() + "\t" + msg);
}

function sha1(str) {
    var sha1 = crypto.createHash("sha1"); //定义加密方式:md5不可逆,此处的md5可以换成任意hash加密的方法名称;
    sha1.update(str);
    var res = sha1.digest("hex"); //加密后的值d
    return res;
}

function getTime() {
    var now = new Date();
    var hours = now.getHours();
    var minutes = now.getMinutes();
    var seconds = now.getSeconds();
    if (hours < 10) {
        hours = "0" + hours;
    }
    if (minutes < 10) {
        minutes = "0" + minutes;
    }
    if (seconds < 10) {
        seconds = "0" + seconds;
    }
    return hours + ":" + minutes + ":" + seconds;
}
function randInt(length){
    var str = "";
    var arr = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];
 
    for(var i=0; i<length; i++){
        str += arr[rand(0,arr.length-1)];
    }
    return str;
}
function randStr(length){
    var str = "";
    var arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
 
    for(var i=0; i<length; i++){
        str += arr[rand(0,arr.length-1)];
    }
    return str;
}

var BaseRequest={};
var progressWaiting=false,progressListen=false;
var nowUuid;
var Config={};
app.get('/welcome/', function(req, res) {
    var param = req.query.id;
    BaseRequest.DeviceID="e"+randInt(15);
    if(!progressWaiting){
        //等待处理结果
        var url = "https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_="+getTimeStamps()+rand(100,999);
        
        request(url, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var code = getSubstr(body,'window.QRLogin.code = ','; window.QRLogin.uuid');
                nowUuid = getSubstr(body,'window.QRLogin.uuid = "','";');
                debug("Waiting for scan result");
                res.setHeader("Refresh",10);
                res.send('<center><img width="200px" src="https://login.weixin.qq.com/qrcode/'+nowUuid+'"/><br>请在10s内扫描</center>');
                res.end();
                progressWaiting=true;
                
            }else{
                res.end("Error");
            }
        });
    }else{
        var isResponsed=false;
        var time=getTimeStamps();
        var checkTime=~time;
        url="https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid="+nowUuid+"&tip=1&r="+checkTime+"&_="+time;
        request(url, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                isResponsed=true;
                var code = getSubstr(body,'window.code=',';');
                switch (code){
                    case "200":
                        url=getSubstr(body,'window.redirect_uri="','";');
                        url+="&fun=new&version=v2";
                        request(url, function (error, response, body) {
                            if (!error && response.statusCode == 200) {
                                BaseRequest.skey=getSubstr(body,'<skey>','</skey>');
                                BaseRequest.Sid=getSubstr(body,'<wxsid>','</wxsid>');
                                BaseRequest.Uin=getSubstr(body,'<wxuin>','</wxuin>');
                                BaseRequest.pass_ticket=getSubstr(body,'<pass_ticket>','</pass_ticket>');
                                var cookieArr=response.headers['set-cookie'];
                                Config.cookie="";
                                cookieArr.forEach(function (cookie){
                                    var c=getSubstr(cookie,"",'; Domain');
                                    Config.cookie+=c+"; ";
                                });
                                debug("Wechat login success!");
                                res.end();
                                url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r="+(~getTimeStamps())+"&pass_ticket="+BaseRequest.pass_ticket;
                               
                                request({
                                    url: url,
                                    method: "POST",
                                    json: false,
                                    headers: {
                                    "content-type": "application/json",
                                    },
                                    body: JSON.stringify({"BaseRequest":BaseRequest})
                                }, 
                                function(error, response, body) {
                                    if (!error && response.statusCode == 200) {
                                        body=JSON.parse(body);
                                        Config.myinfo=body.User;
                                        Config.last=body.SyncKey;
                                        debug("Listen wechat message...");
                                        //Now start listen wechat message
                                        if(!progressListen){
                                            //if not listenning...
	                                        msgloop();
	                                        progressListen=true;
                                        }
                                    }else{
                                        debug("Listen wechat message error");
                                    }
                                }); 
        
                            }else{
                                debug("Wechat login error!");
                            }
                        });
                        break;
                    case "201":
                        res.setHeader("Refresh",1);
                        res.end("Please confirm the login request!");
                        debug("Please confirm the request of login");
                        break;
                    case "408":
                        progressWaiting=false;
                        debug("Login timeout and refresh please");
                        break;
                    default:
                        res.setHeader("Refresh",1);
                        res.end();
                        progressWaiting=false;
                        console.log(body);
                }
            }else{
                progressWaiting=false;
                debug("Error with "+response.statusCode);
            }
        });
        setTimeout(function() {
            if(!isResponsed){
                progressWaiting=false;
                res.setHeader("Refresh",1);
                res.end();
            }
        }, 3000);
    }
});
function msgloop(){
    debug("Getting Message...");
    url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid="+BaseRequest.Sid+"&skey="+BaseRequest.skey+"&lang=zh_CN&pass_ticket="+BaseRequest.pass_ticket;
	                                    
    request({
        url: url,
        method: "POST",
        json: false,
        headers: {
        "content-type": "application/json",
        },
        body: JSON.stringify({"BaseRequest":BaseRequest,"SyncKey":Config.last,"rr":(~getTimeStamps())})
    }, 
    function(error, response, body) {
        if (!error && response.statusCode == 200) {
            body=JSON.parse(body);
            //console.log(body);
            Config.last=body.SyncKey;
            body.AddMsgList.forEach(function (msg){
                console.log("MSG from "+msg.FromUserName+" : "+msg.Content);
                var fromType=msg.FromUserName.substring(0,2);
                if(fromType=="@@"){
                    //群消息
                    debug("Msg From Group : "+msg.Content);
                    responseMsg(msg.FromUserName,"[自动回复]:"+msg.Content);
                }else{
                    fromType=msg.FromUserName.substring(0,1);
                    if(fromType=="@"){
                        //个人消息
                        debug("Msg From Person : "+msg.Content);
                        responseMsg(msg.FromUserName,"[自动回复]:"+msg.Content);
                    }else{
                        //公众号消息
                        debug("Msg From MpAccount : "+msg.Content);
                    }
                }
                
            });
        }
        setTimeout(function(){
            msgloop();
        },rand(1000,5000));
    }); 
}
function responseMsg(FromUserName,Content){
    var url="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?lang=zh_CN&pass_ticket="+BaseRequest.pass_ticket;
    var localId=(getTimeStamps()+rand(100,999));
                                            
    request({
        url: url,
        method: "POST",
        json: false,
        headers: {
        "content-type": "application/json",
        },
        body: JSON.stringify({"BaseRequest":BaseRequest,"Msg":{
            "ClientMsgId":localId,
            "Content":Content,
            "FromUserName":Config.myinfo.UserName,
            "LocalID":localId,
            "ToUserName":FromUserName,
            "Type":1
        },"Scene":0})
    }, 
    function(error, response, body) {
        debug("Message response success!");
    });
            
}
app.get('/*', function(req, res) {
    var params = req.originalUrl;
    res.send("<center><h1>808 Not Found</h1><hr>Nginx&Node</center>");
});

var server = app.listen(10002, function() {
    //var host = server.address().address
    //var port = server.address().port
    debug("Server running...");
});