博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nodejs 黑名单中间件设计
阅读量:6002 次
发布时间:2019-06-20

本文共 8326 字,大约阅读时间需要 27 分钟。

hot3.png

黑名单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);

转载于:https://my.oschina.net/wanglihui/blog/270339

你可能感兴趣的文章
OpenSSH利用处理畸形长度密码造成的时间差,枚举系统用户(CVE-2016-6210)
查看>>
Javascript回调函数
查看>>
可能是最简单的面向对象入门教程(二)为什么要有类型
查看>>
配置Openfiler做ISCS实验
查看>>
Maven启用代理访问
查看>>
LDAP & Implementation
查看>>
Codeigniter处理用户登录验证后URL跳转
查看>>
hdu 4597 Play Game
查看>>
hdu 1398 Square Coins (母函数)
查看>>
试验性的Numpy教程(译)
查看>>
twitter storm 源码走读之5 -- worker进程内部消息传递处理和数据结构分析
查看>>
CCF 201503-4 网络延时
查看>>
oracle管理控制台不能打开,提示此网站的安全证书有问题?
查看>>
.net获取select控件中的文本内容
查看>>
Windows 8 Metro App开发[5]导航栏(AppBar)的使用
查看>>
shell expect
查看>>
Effective Java -- 使可变性最小化
查看>>
开发环境中Docker的使用
查看>>
Redis 分布式锁
查看>>
IBM、HPUX、Solaris不同之处
查看>>