nodejs实现黑名单中间件设计
nodejs实现黑名单中间件设计
发布时间:2016-12-30 来源:查字典编辑
摘要:黑名单Schema:复制代码代码如下:/***CreatedbyYCXJ-wanglihuion2014/5/28.*/'usestrict...

黑名单Schema:

复制代码 代码如下:

/**

* Created by YCXJ-wanglihui on 2014/5/28.

*/

'use strict';

var mongoose = require('mongoose');

var Schema = mongoose.Schema;

//1.短暂屏蔽 2.永久屏蔽

var degree = {TEMP:1, FOREVER:2};

/**

* 黑名单

* @type {Schema}

*

* @param ip {String} 黑名单Ip

* @param createAt {Date} 创建时间

* @param expireTime {Date} 如果是短暂屏蔽,屏蔽到期时间

* @param forbiddenDegree {Number} 屏蔽级别 1.短暂屏蔽 2.永久屏蔽

* @param reason {String} 屏蔽原因

*/

var BlackList = new Schema({

ip:{

type: String,

index:true

},

createAt:{

type: Date,

default: Date.now

},

expireTime:{

type: Date

},

forbiddenDegree:{

type: Number,

default:degree.TEMP

},

reason:{

type: String,

default: '请求次数频繁'

}

});

mongoose.model('BlackList', BlackList);

IP与提交记录Schema:

复制代码 代码如下:

/**

* Created by YCXJ-wanglihui on 2014/5/28.

*/

'use strict';

var mongoose = require('mongoose');

var Schema = mongoose.Schema;

var ObjectId = Schema.ObjectId;

/**

* 记录参与调查问卷的回复与Ip

* @type {Schema}

*

* @param answerId {ObjectId} 回复Id

* @param createAt {Date} 创建时间

* @param ip {String} 参与回复的人Ip

*/

var IpAnswerLog = new Schema({

answerId: {

type: ObjectId

},

createAt: {

type: Date,

default:Date.now

},

ip:{

type: String,

index:true

}

});

mongoose.model('IpAnswerLog', IpAnswerLog);

相关Proxy代码:

复制代码 代码如下:

/**

* Created by YCXJ-wanglihui on 2014/5/28.

*/

'use strict';

var IpAnswerLog = require('../models').IpAnswerLog;

/**

* 新建并保存

* @param ipAnswerLog {Schema or dict}

* @param callback

*/

var newAndSave = function(ipAnswerLog, callback){

if(ipAnswerLog instanceof IpAnswerLog){

ipAnswerLog.save(callback);

}else{

var m = new IpAnswerLog(ipAnswerLog);

m.save(callback);

}

}

/**

* 一分钟内回复数

* @param ip

* @param callback

*/

var countOneMinuteAnswer = function(ip, callback){

var endTime = Date.now();

var beginTime = endTime - 1000*60*1;

countIpAnswerByTime(beginTime, endTime, ip, callback);

}

/**

* 一小时内回复数字

* @param ip

* @param callback

*/

var countOneHourAnswer = function(ip, callback){

var endTime = Date.now();

var beginTime = endTime - 1000*60*60*1;

countIpAnswerByTime(beginTime, endTime, ip, callback);

}

/**

* 一天内回复

* @param ip

* @param callback

*/

var countOneDayAnswer = function(ip, callback){

var endTime = Date.now();

var beginTime = endTime - 1000*60*60*24;

countIpAnswerByTime(beginTime, endTime, ip, callback);

}

/**

* 计算某段时间内回复数

* @param beginTime {Number} 开始时间 时间戳

* @param endTime {Number} 结束时间 如果为null,使用当前时间 时间戳

* @param ip {String} Ip地址

* @param callback

*/

var countIpAnswerByTime = function(beginTime, endTime, ip, callback){

if(!endTime){

endTime = Date.now();

}

IpAnswerLog.count({ip:ip, '$and':{$lt:beginTime, $gt:endTime}}, callback);

}

exports.countIpAnswerByTime =countIpAnswerByTime;

exports.countOneDayAnswer = countOneDayAnswer;

exports.countOneHourAnswer = countOneHourAnswer;

exports.countOneMinuteAnswer = countOneMinuteAnswer;

exports.newAndSave = newAndSave;

黑名单Proxy:

复制代码 代码如下:

/**

* Created by YCXJ-wanglihui on 2014/5/28.

*/

'use strict';

var BlackList = require('../models').BlackList;

/**

* 新建并保存

* @param backList {BlackList} or {dict} 黑名单数据

* @param callback

*/

var newAndSave = function(backList, callback){

if(backList instanceof BlackList){

backList.save(callback);

}else{

var m = new BlackList(backList);

m.save(callback);

}

}

/**

* 禁用Ip访问一小时

* @param ip {String}

* @param callback

*/

var newAndSaveOneHourTempForbidden = function(ip, callback){

var expireTime = Date.now() + 1000*60*60;

newAndSaveTempForbidden(ip,expireTime, callback);

}

/**

* 禁用一天

* @param ip {String}

* @param callback

*/

var newAndSaveOneDayTempForbidden = function(ip, callback){

var expireTime = Date.now() + 1000*60*60*24;

newAndSaveTempForbidden(ip, expireTime, callback);

}

/**

* 新建临时黑名单

* @param ip {String}

* @param expireTime {Number} 到期时间

* @param callback

*/

var newAndSaveTempForbidden = function(ip, expireTime,callback){

var blackList = new BlackList({ip:ip, expireTime:expireTime, forbiddenDegree:1});

newAndSave(blackList, callback);

}

/**

* 新建并保存永久黑名单

* @param ip

* @param callback

*/

var newAndSaveForeverForbidden = function(ip, callback){

var blackList = new BlackList({ip:ip, forbiddenDegree:2});

newAndSave(blackList, callback);

}

/**

* 判断是否在黑名单中

* @param ip {String} Ip地址

* @param callback

*/

var isInBlackList = function(ip, callback){

getBlackListByIp(ip, function(err, blackList){

if(err){

callback(err);

}else if(blackList){

var currentDate = Date.now();

if(blackList.forbiddenDegree ===1 && blackList.expireTime> currentDate){

removeBlackListByIp(ip, function(err){

if(err){

callback(err);

}else{

callback(null, false);

}

})

}else{

callback(null, true);

}

}else{

callback(null, false);

}

})

}

/**

* 通过Ip获取黑名单条目

* @param ip

* @param callback

*/

var getBlackListByIp = function(ip, callback){

BlackList.findOne({ip:ip}, callback);

}

/**

* 根据Ip删除黑名单

* @param ip

* @param callback

*/

var removeBlackListByIp = function(ip, callback){

getBlackListByIp(ip, function(err, blackList){

if(err){

callback(err);

}else if(blackList){

blackList.remove(callback);

}else{

callback(null,null);

}

})

}

exports.newAndSave = newAndSave;

exports.isInBlackList = isInBlackList;

exports.getBlackListByIp = getBlackListByIp;

exports.removeBlackListByIp = removeBlackListByIp;

exports.newAndSaveOneHourTempForbidden = newAndSaveOneHourTempForbidden;

exports.newAndSaveOneDayTempForbidden = newAndSaveOneDayTempForbidden;

exports.newAndSaveForeverForbidden = newAndSaveForeverForbidden;

exports.newAndSaveTempForbidden = newAndSaveTempForbidden;

中间件详情:

复制代码 代码如下:

/**

* Created by YCXJ-wanglihui on 2014/5/28.

*/

'use strict';

var BlackListProxy = require('../../proxy').BlackListPorxy;

var IpAnswerLogProxy = require('../../proxy').IpAnswerLogProxy;

var EventProxy = require('eventproxy');

/**

* 判断是否需要将Ip移动至黑名单中

* @param req

* @param res

* @param next

*/

var isNeedMoveToBlackList = function(req, res, next){

var ip = req.ip;

//判断是否在黑名单中

requireNotInBlackList(req, res, function(){

var ep = new EventProxy();

ep.fail(next);

ep.all('minuteCount', 'hourCount', 'dayCount', function(minuteCount, hourCount, dayCount){

if(minuteCount > 10){

BlackListProxy.newAndSaveOneHourTempForbidden(ip, function(err, blackList){

if(err){

return next(err);

}else{

return res.send('提交过于频繁,1小时后重试!');

}

});

}else if(hourCount > 100){

BlackListProxy.newAndSaveOneDayTempForbidden(ip, function(err, blackList){

if(err){

return next(err);

}else{

return res.send('提交过于频繁,1天后重试!');

}

})

}else if(dayCount > 1000){

BlackListProxy.newAndSaveOneDayTempForbidden(ip, function(err, blackList){

if(err){

return next(err);

}else{

return res.send('提交过于频繁,1天后重试!');

}

})

}else{

return next();

}

})

IpAnswerLogProxy.countOneMinuteAnswer(ip,ep.done('minuteCount'));

IpAnswerLogProxy.countOneHourAnswer(ip, ep.done('hourCount'));

IpAnswerLogProxy.countOneDayAnswer(ip, ep.done('dayCount'));

});

}

/**

* 中间件 要求Ip不在黑名单中

* @param req

* @param res

* @param next

*/

var requireNotInBlackList = function(req, res, next){

var ip = req.ip;

BlackListProxy.isInBlackList(ip, function(err, result){

if(err){

next(err);

}else if(result){

return res.send('您的Ip禁止提交,如有疑问请联系lihui.wang@tulingdao.com');

}else{

next();

}

})

}

exports.isNeedMoveToBlackList = isNeedMoveToBlackList;

exports.requireNotInBlackList = requireNotInBlackList;

在路由中使用:

复制代码 代码如下:

//网页提交接口

router.post('/create', middleware.isNeedMoveToBlackList, paperAnswers.create);

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Javascript教程学习
热门Javascript教程学习
编程开发子分类