1 Star 0 Fork 21

frank / Qvisitor

forked from arrowing / Qvisitor 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
index.js 9.43 KB
一键复制 编辑 原始数据 按行查看 历史
var exp = require('express'),
request = require('superagent'),
bodyParser = require('body-parser'),
logger = require('morgan'),
url = require('url'),
app = exp(),
server,
db = require('./db'),
config = require('./config'),
getPassword = require('./getPassword'),
getVerifyCode = require('./getVerifyCode'),
login = require('./login'),
getSidCode = require('./getSidCode'),
getVisitors = require('./getVisitors'),
User = db.connection.model('user', db.UserModel);
//监听db close event并重新连接
db.connection.on('close', function () {
console.log('db was closed, try open again.');
db.openDb(function() {
User = db.connection.model('user', db.UserModel);
});
});
//基本设置
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');
app.set('view cache', true);
app.use(bodyParser());
app.use(exp.static(__dirname + '/public'));
app.use(logger('short'));
//路由设置
app.get('/', function(req, res){
res.render('index');
});
//获取被拦访客
app.post('/getVisitor/:mode?', function(req, mainRes){
var qq = parseInt(req.body.qq),
pass = req.body.pass,
vcInput = req.body.vcInput.toUpperCase(),
qvPage = req.body.qvPage, //分页参数
data = {
page: qvPage
},
md5Pass = getPassword(qq, pass, config.AB_VERIFYCODE),
currentCount = 0,
result = {
status: 'failure',
msg: '系统繁忙,请过段时间再尝试'
};
//获取更多被拦访客
if(req.params.mode == 'loadMore'){
result.mode = req.params.mode;
}else{
result.mode = '';
};
//假如是已经输入验证码的,先检查验证码后登录
if(vcInput){
//获取用户sig码
User.findOne({account: qq})
.exec(function(err, doc){
if(doc && !!doc.sig){
var sigHeaders = config.HEADERS;
sigHeaders.Cookie = 'g_ut=3';
sigHeaders.Referer = 'http://captcha.qq.com/cap_union_show?captype=3&aid=549000929&uin='+qq+'&cap_cd='+doc.cap_cd+'&v='+Math.random();
sigHeaders.Host = config.GET_SIG_HOST;
//检查验证码是否有误
request.get(config.CHECK_VC_URL)
.set(sigHeaders)
.query({
aid: config.LOGIN_PARAMS.aid,
uin: qq,
captype: 0,
ans: vcInput,
sig: doc.sig,
r: Math.random()
})
.buffer()
.end(function(res){
var resArr = res.text.match(/rcode:(\d),randstr:\"(.*?)\",sig:\"(.*?)\"/),
status = resArr[1],
loginSig = resArr[3];
if(status == 0){//验证码正确
data.loginSig = loginSig;
data.verifycode = vcInput;
step2();
}else{//res.text : cap_InnerCBVerify({rcode:5,randstr:"",sig:"",errmsg:"验证失败,请重试。"});
result.msg = '验证失败,请重试。';
result.type = 'refresh';
mainRes.send(result);
};
console.log('check verifycode result : ' + res.text);
});
}else{//没有sig码肯定是错误的
mainRes.send(result);
};
});
}else{
//开始工作,从第一步开始
step1();
};
// 第一步:获取验证码和cookie
function step1(){
//本次查询次数过多,取消进入循环
if(++currentCount >= config.TIMEOUT_COUNT) return;
result.step_error = 1;
User.where('account', qq)
.where('pass').in([pass, md5Pass])
.limit(1)
.exec(function(err, doc){
if(doc && doc.length && !!doc[0].sid){//假如sid已存在,则直接获取访客
//说明用户在cookie里保存了密码,不需要再加密密码了
if(doc[0].pass == pass){
md5Pass = pass;
};
data.sid = doc[0].sid;
step4();
}else{
getVerifyCode({
qq: qq,
callback: step2,
backData: data
});
};
console.log('now login user : ' + qq);
});
};
// 第二步:验证码存在则登录
function step2(){
if(!data.verifycode){
return finalFn();
};
console.log('step1...[get verifycode]: \033[92m'+ data.verifycode +'\033[39m');
result.step_error = 2;
//需要获取验证码图片
if(data.cap_cd){
result.cap_cd = data.cap_cd;
result.msg = '需要输入验证码';
mainRes.send(result);
}else{
login({
verifycode: data.verifycode,
qq: qq,
pass: pass,
cookies: data.cookies,
callback: step3,
backData: data,
loginSig: data.loginSig || ''
});
};
};
// 第三步:根据登陆后的首页获取sid码
function step3(){
//帐号或密码错误
if(data.loginErr == 3){
result.type = 'refresh';
result.msg = '帐号或密码错误';
}else if(data.loginErr == 4 && data.cap_cd){
result.type = 'refresh';
result.msg = '您输入的验证码不正确,请重新输入。';
};
if(!data.loginedUrl){
console.log('\033[31merror account or password\033[39m, qq is ' + qq);
return finalFn();
};
console.log('step2...[login and get loginedUrl]: \033[92m'+ data.loginedUrl +'\033[39m');
result.step_error = 3;
getSidCode({
loginedUrl: data.loginedUrl,
callback: step4,
backData: data
});
};
// 第四步:成功返回被拦截访客列表
function step4(){
if(!data.sid){
return finalFn();
};
console.log('step3...[get sid]: \033[92m'+ data.sid +'\033[39m');
result.step_error = 4;
getVisitors({
qq: qq,
sid: data.sid,
callback: finalFn,
backData: data,
mode: result.mode
});
};
// 成功响应或者失败返回
function finalFn(){
var visitors, user;
if(data.visitors){
visitors = data.visitors;
//code -11334 系统繁忙,sid失效
if(visitors.code != 0 || visitors.subcode != 0 || visitors.message != ''){
//sid失效,重新获取
console.log('step finally...[error]: \033[31mreturn step 1\033[39m');
User.remove({account: qq}, function(err){
console.log('clear user message: ' + (err ? '\033[31merror\033[39m' : '\033[92mok\033[39m') );
});
return step1();
}else{
console.log('step finally...[get visitors]: \033[92m'+ (result.mode || 'normal' ) +' mode\033[39m');
//保存用户sid信息
user = {
account: qq,
pass: md5Pass,
sid: data.sid,
date: + new Date()
};
User.update(
{account: qq},
user,
{upsert: true},
function(err){
console.log('save user message: ' + (err ? '\033[31merror\033[39m' : '\033[92m'+ qq +'\033[39m') );
}
);
};
result.step_error = 0;
result.status = 'success';
result.msg = '获取被拦访客成功';
result.visitors = visitors;
result.qq = qq;
result.pass = md5Pass;
result.page = data.page;//翻页使用参数
};
result.errmsg = data.errorMsg || '';
mainRes.send(result);
};
});
//突破防盗链获取QQ用户头像
app.get('/getFace', function(req, faceRes){
var faceUrl = req.query.faceUrl,
tmpUrl = url.parse(faceUrl);
request.get(faceUrl)
.set('Host', tmpUrl.hostname)
.end(function(res){
res.pipe(faceRes);
});
});
//需要输入验证码,获取验证码图片
app.get('/getVerifycodeImg', function(req, vcRes){
var qq = req.query.qq,
cap_cd = req.query.cap_cd,
headers = config.HEADERS,
sigReg = /\".*\"/;
headers.Cookie = 'g_ut=3';
headers.Referer = 'http://captcha.qq.com/cap_union_show?captype=3&aid=549000929&uin='+qq+'&cap_cd='+cap_cd+'&r='+Math.random();
headers.Host = config.GET_SIG_HOST;
//得到SIG码
request.get(config.GET_SIG_URL)
.query({
uin: qq,
aid: config.LOGIN_PARAMS.aid,
r: Math.random()
})
.set(headers)
.buffer()
.end(function(res){
var sigTmp = res.text.match(sigReg)[0],
sig = sigTmp.split('"')[1],
user;
console.log('sig text : ' + res.text);
//储存用户sig码
user = {
account: qq,
sig: sig,
cap_cd: cap_cd,
date: + new Date()
};
User.update(
{account: qq},
user,
{upsert: true},
function(err){
console.log('save user sig: ' + (err ? '\033[31merror\033[39m' : '\033[92m'+ sig +'\033[39m') );
}
);
//得到验证码图片
request.get(config.GET_VC_URL)
.query({
uin: qq,
aid: config.LOGIN_PARAMS.aid,
sig: sig
})
.set(headers)
.end(function(res){
res.pipe(vcRes);
});
});
});
server = app.listen(config.IS_LOCAL ? 3000 : config.SERVER_PORT, function() {
console.log('Listening on port %d', server.address().port);
});
process.on('SIGTERM', function () {
server.close(function () {
process.exit(0);
});
});
1
https://gitee.com/noikiy/Qvisitor.git
git@gitee.com:noikiy/Qvisitor.git
noikiy
Qvisitor
Qvisitor
master

搜索帮助