Authored by yyq

Merge branch 'feature/apiLimit' into release/0606

... ... @@ -10,6 +10,7 @@ const sender = global.yoho.apmSender;
const config = global.yoho.config;
const hostname = require('os').hostname();
const routeEncode = require('./route-encode');
const pathWhiteList = require('./limiter/rules/path-white-list');
const _ = require('lodash');
const forceNoCache = (res) => {
... ... @@ -161,32 +162,34 @@ exports.serverError = () => {
}));
}
} else if (err.code === 9999991 || err.code === 9999992) {
let remoteIp = req.yoho.clientIp;
if (!_.includes(pathWhiteList(), req.path)) {
let remoteIp = req.yoho.clientIp;
const isHuman = await cache.getAsync(`${config.app}:limiter:api:ishuman:${remoteIp}`);
const isHuman = await cache.getAsync(`${config.app}:limiter:api:ishuman:${remoteIp}`);
if (!isHuman) {
if (remoteIp.indexOf(',') > 0) {
let arr = remoteIp.split(',');
if (!isHuman) {
if (remoteIp.indexOf(',') > 0) {
let arr = remoteIp.split(',');
remoteIp = arr[0];
}
cache.setAsync(`${config.app}:limiter:${remoteIp}`, 1, config.LIMITER_IP_TIME);
let limitAPI = helpers.urlFormat('/3party/check', {refer: req.get('Referer') || ''});
let limitPage = helpers.urlFormat('/3party/check', {
refer: req.protocol + '://' + req.get('host') + req.originalUrl
});
remoteIp = arr[0];
}
cache.setAsync(`${config.app}:limiter:${remoteIp}`, 1, config.LIMITER_IP_TIME);
req.session.apiLimitValidate = true;
if (req.xhr) {
return res.status(510).json({
code: err.code,
data: {refer: limitAPI}
let limitAPI = helpers.urlFormat('/3party/check', {refer: req.get('Referer') || ''});
let limitPage = helpers.urlFormat('/3party/check', {
refer: req.protocol + '://' + req.get('host') + req.originalUrl
});
}
return res.redirect(limitPage);
req.session.apiLimitValidate = true;
if (req.xhr) {
return res.status(510).json({
code: err.code,
data: {refer: limitAPI}
});
}
return res.redirect(limitPage);
}
}
return _err510(req, res, 510, err);
... ...
... ... @@ -5,6 +5,7 @@ const logger = global.yoho.logger;
const ip = require('./rules/ip-list');
const userAgent = require('./rules/useragent');
const ipWhiteList = require('./rules/ip-white-list');
const pathWhiteList = require('./rules/path-white-list');
const qpsLimiter = require('./rules/qps-limit');
const co = Promise.coroutine;
... ... @@ -32,31 +33,6 @@ const IP_WHITE_SEGMENT = [
'10.66.', // 内网IP段
'192.168.' // 内网IP段
];
const PATH_WHITE_LIST = [
'/3party/check',
'/3party/check/submit',
'/passport/captcha/get',
'/passport/img-check.jpg',
'/passport/geetest/register',
'/activity/individuation',
'/activity/individuation/coupon',
'/activity/share',
'/activity/wechat/share',
'/activity/wechat/1111',
'/api/switch',
'/passport/login/user',
'/sw.js',
'/manifest.json',
'/activity/sw.js',
'/activity/manifest.json',
'/hfxRaNY27L.txt',
'/activity/hfxRaNY27L.txt',
'/product/shop/hfxRaNY27L.txt',
'/product/hfxRaNY27L.txt',
'/.well-known/apple-app-site-association',
'/service/sitemap.xml',
'/node/status.html'
];
const limiter = (rule, policy, context) => {
return rule(context, policy);
... ... @@ -74,7 +50,7 @@ const _excluded = (req) => {
atWhiteList ||
_.includes(IP_WHITE_LIST, remoteIp) ||
_.includes(IP_WHITE_SEGMENT, remoteIpSegment) ||
_.includes(PATH_WHITE_LIST, req.path) ||
_.includes(pathWhiteList(), req.path) ||
req.xhr ||
!_.isEmpty(_.get(req, 'user.uid'))
);
... ...
const _ = require('lodash');
const logger = global.yoho.logger;
const cache = global.yoho.cache.master;
const WHITE_LIST_KEY = 'wap:limiter:whitelist:path';
const DEFAULT_PATH_WHITE_LIST = [
'/3party/check',
'/3party/check/submit',
'/passport/captcha/get',
'/passport/img-check.jpg',
'/passport/geetest/register',
'/activity/individuation',
'/activity/individuation/coupon',
'/activity/share',
'/activity/wechat/share',
'/activity/wechat/1111',
'/api/switch',
'/passport/login/user',
'/sw.js',
'/manifest.json',
'/activity/sw.js',
'/activity/manifest.json',
'/hfxRaNY27L.txt',
'/activity/hfxRaNY27L.txt',
'/product/shop/hfxRaNY27L.txt',
'/product/hfxRaNY27L.txt',
'/.well-known/apple-app-site-association',
'/service/sitemap.xml',
'/node/status.html'
];
const cacheWhiteList = {
nowTime() {
return Date.parse(new Date()) / 1000;
},
getValue() {
if (this.updateTime || this.nowTime() - this.updateTime > 60 * 10) {
this.syncRemoteConfig();
}
return _.uniq(_.concat([], DEFAULT_PATH_WHITE_LIST, _.toArray(this.whiteList)));
},
syncRemoteConfig() {
if (this.syncing) {
return;
}
this.syncing = true;
cache.getAsync(WHITE_LIST_KEY).then(res => {
this.updateTime = this.nowTime();
if (!res) {
return;
}
this.whiteList = JSON.parse(res);
this.syncing = false;
}).catch((e) => {
this.syncing = false;
logger.debug('whitelist path parse error. ' + JSON.stringfy(e));
});
}
};
module.exports = () => {
return cacheWhiteList.getValue();
};
... ...
... ... @@ -19,13 +19,13 @@ module.exports = (limiter, policy) => {
let whitelist = [];
try {
blacklist = JSON.parse(args[0]);
blacklist = JSON.parse(args[0]) || [];
} catch (error) {
logger.error(error);
}
try {
whitelist = JSON.parse(args[1]);
whitelist = JSON.parse(args[1]) || [];
} catch (error) {
logger.error(error);
}
... ...
... ... @@ -49,8 +49,12 @@ $(document).ajaxError((event, xhr) => {
window.location.href = `/signin.html?refer=${encodeURIComponent(window.location.href)}`;
}
}
} else if (xhr.status === 510 && xhr.responseJSON.data && xhr.responseJSON.data.refer) {
window.location.href = xhr.responseJSON.data.refer;
} else if (xhr.status === 510) {
if (xhr.responseJSON.data && xhr.responseJSON.data.refer) {
window.location.href = xhr.responseJSON.data.refer;
} else if (xhr.responseJSON.message) {
tip.show(xhr.responseJSON.message);
}
} else if (xhr.status === 403 && xhr.responseJSON.code === 4403) {
tip.show(xhr.responseJSON.message);
setTimeout(function() {
... ...