...
|
...
|
@@ -4,7 +4,9 @@ const _ = require('lodash'); |
|
|
const logger = global.yoho.logger;
|
|
|
const ip = require('./rules/ip-list');
|
|
|
const userAgent = require('./rules/useragent');
|
|
|
const ipWhiteList = require('./rules/ip-white-list');
|
|
|
const qpsLimiter = require('./rules/qps-limit');
|
|
|
const co = Promise.coroutine;
|
|
|
|
|
|
// const asynchronous = require('./rules/asynchronous');
|
|
|
// const fakerLimiter = require('./rules/faker-limit');
|
...
|
...
|
@@ -58,19 +60,44 @@ const limiter = (rule, policy, context) => { |
|
|
return rule(context, policy);
|
|
|
};
|
|
|
|
|
|
module.exports = (req, res, next) => {
|
|
|
// 排除条件:ip白名单/路径白名单/异步请求/登录用户
|
|
|
const _excluded = (req) => {
|
|
|
let remoteIp = req.yoho.clientIp || '';
|
|
|
let remoteIpSegment = `${remoteIp.split('.').slice(0, 2).join('.')}.`;
|
|
|
|
|
|
return co(function* () {
|
|
|
let cacheIpWhiteList = yield ipWhiteList();
|
|
|
|
|
|
return Boolean(
|
|
|
_.includes(cacheIpWhiteList, remoteIp) ||
|
|
|
_.includes(IP_WHITE_LIST, remoteIp) ||
|
|
|
_.includes(IP_WHITE_SEGMENT, remoteIpSegment) ||
|
|
|
_.includes(PATH_WHITE_LIST, req.path) ||
|
|
|
req.xhr ||
|
|
|
!_.isEmpty(_.get(req, 'user.uid'))
|
|
|
);
|
|
|
})();
|
|
|
};
|
|
|
|
|
|
// 排除条件:ip白名单/路径白名单/异步请求/登录用户
|
|
|
const excluded = _.includes(IP_WHITE_LIST, remoteIp) ||
|
|
|
_.includes(IP_WHITE_SEGMENT, `${remoteIp.split('.').slice(0, 2).join('.')}.`) ||
|
|
|
_.includes(PATH_WHITE_LIST, req.path) || req.xhr || !_.isEmpty(_.get(req, 'user.uid'));
|
|
|
module.exports = (req, res, next) => {
|
|
|
const remoteIp = req.yoho.clientIp || '';
|
|
|
const enabled = !_.get(req.app.locals, 'wap.sys.noLimiter');
|
|
|
|
|
|
// 开关为关或者未获取到remoteIp,放行
|
|
|
if (!enabled || !remoteIp) {
|
|
|
logger.debug(`request remote ip: ${remoteIp}; enabled: ${enabled}`);
|
|
|
return next();
|
|
|
}
|
|
|
|
|
|
co(function* () {
|
|
|
let excluded = yield _excluded(req);
|
|
|
|
|
|
logger.debug(`request remote ip: ${remoteIp}; excluded: ${excluded}; enabled: ${enabled}`);
|
|
|
|
|
|
// 判断获取remoteIp成功,并且开关未关闭
|
|
|
if (enabled && remoteIp && !excluded) {
|
|
|
// 白名单,放行
|
|
|
if (excluded) {
|
|
|
return next();
|
|
|
}
|
|
|
const context = {
|
|
|
req: req,
|
|
|
res: res,
|
...
|
...
|
@@ -78,14 +105,15 @@ module.exports = (req, res, next) => { |
|
|
remoteIp: remoteIp
|
|
|
};
|
|
|
|
|
|
Promise.all([
|
|
|
let results = yield Promise.all([
|
|
|
limiter(userAgent, captchaPolicy, context),
|
|
|
limiter(ip, captchaPolicy, context),
|
|
|
limiter(qpsLimiter, captchaPolicy, context)
|
|
|
|
|
|
// limiter(asynchronous, captchaPolicy, context)
|
|
|
// limiter(fakerLimiter, reporterPolicy, context)
|
|
|
]).then((results) => {
|
|
|
]);
|
|
|
|
|
|
let allPass = true, exclusion = false, policy = null;
|
|
|
|
|
|
logger.debug('limiter result: ' + JSON.stringify(results));
|
...
|
...
|
@@ -108,12 +136,8 @@ module.exports = (req, res, next) => { |
|
|
} else {
|
|
|
return next();
|
|
|
}
|
|
|
|
|
|
}).catch((err) => {
|
|
|
})().catch(err => {
|
|
|
logger.error(err);
|
|
|
return next();
|
|
|
});
|
|
|
} else {
|
|
|
return next();
|
|
|
}
|
|
|
}; |
...
|
...
|
|