Authored by 郭成尧

ip-white-list

... ... @@ -159,6 +159,8 @@ try {
app.use(require('./doraemon/middleware/limiter'));
}
app.use(require('./doraemon/middleware/limiter'));
if (app.locals.devEnv) {
app.use(devtools());
}
... ...
... ... @@ -13,14 +13,15 @@ const isTest = process.env.NODE_ENV === 'test';
const domains = {
api: 'http://api.yoho.cn/',
service: 'http://service.yoho.cn/',
liveApi: 'http://testapi.live.yohops.com:9999/',
singleApi: 'http://api-test3.yohops.com:9999/',
// api: 'http://api.yoho.cn/',
// service: 'http://service.yoho.cn/',
// liveApi: 'http://testapi.live.yohops.com:9999/',
// singleApi: 'http://api-test3.yohops.com:9999/',
// gray
// api: 'http://apigray.yoho.cn/',
// service: 'http://apigray.yoho.cn/',
api: 'http://apigray.yoho.cn/',
service: 'http://apigray.yoho.cn/',
// platformApi: 'http://172.16.6.210:8088/',
... ...
... ... @@ -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');
logger.debug(`request remote ip: ${remoteIp}; excluded: ${excluded}; enabled: ${enabled}`);
// 开关为关或者未获取到remoteIp,放行
if (!enabled || !remoteIp) {
logger.debug(`request remote ip: ${remoteIp}; enabled: ${enabled}`);
return next();
}
// 判断获取remoteIp成功,并且开关未关闭
if (enabled && remoteIp && !excluded) {
co(function* () {
let excluded = yield _excluded(req);
logger.debug(`request remote ip: ${remoteIp}; excluded: ${excluded}; enabled: ${enabled}`);
// 白名单,放行
if (excluded) {
return next();
}
const context = {
req: req,
res: res,
... ... @@ -78,42 +105,39 @@ 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));
_.forEach(results, (result) => {
if (typeof result === 'object' && !exclusion) {
exclusion = result.exclusion;
}
if (typeof result === 'function') {
allPass = false;
policy = result;
}
});
if (exclusion) {
return next();
} else if (!allPass && policy) {
policy(req, res, next);
} else {
return next();
]);
let allPass = true, exclusion = false, policy = null;
logger.debug('limiter result: ' + JSON.stringify(results));
_.forEach(results, (result) => {
if (typeof result === 'object' && !exclusion) {
exclusion = result.exclusion;
}
}).catch((err) => {
logger.error(err);
return next();
if (typeof result === 'function') {
allPass = false;
policy = result;
}
});
} else {
if (exclusion) {
return next();
} else if (!allPass && policy) {
policy(req, res, next);
} else {
return next();
}
})().catch(err => {
logger.error(err);
return next();
}
});
};
... ...
const co = Promise.coroutine;
const cache = global.yoho.cache.master;
const WHITE_LIST_KEY = 'whitelist:ips';
module.exports = () => {
return co(function* () {
let listFromCache = yield cache.getAsync(WHITE_LIST_KEY);
return Promise.resolve(JSON.parse(listFromCache) || []);
})();
};
... ...