Authored by 郝肖肖

'limiter-2-edition'

@@ -70,7 +70,7 @@ module.exports = (req, res, next) => { @@ -70,7 +70,7 @@ module.exports = (req, res, next) => {
70 // 排除条件:ip白名单/路径白名单/异步请求/登录用户 70 // 排除条件:ip白名单/路径白名单/异步请求/登录用户
71 const excluded = _.includes(IP_WHITE_LIST, remoteIp) || 71 const excluded = _.includes(IP_WHITE_LIST, remoteIp) ||
72 _.includes(PATH_WHITE_LIST, req.path) || req.xhr || !_.isEmpty(_.get(req, 'user.uid')); 72 _.includes(PATH_WHITE_LIST, req.path) || req.xhr || !_.isEmpty(_.get(req, 'user.uid'));
73 - const enabled = !_.get(req.app.locals, 'wap.sys.noLimite'); 73 + const enabled = !_.get(req.app.locals, 'pc.sys.noLimiter');
74 74
75 logger.debug(`request remote ip: ${remoteIp}; excluded: ${excluded}; enabled: ${enabled}`); 75 logger.debug(`request remote ip: ${remoteIp}; excluded: ${excluded}; enabled: ${enabled}`);
76 76
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 2
3 const helpers = global.yoho.helpers; 3 const helpers = global.yoho.helpers;
4 const _ = require('lodash'); 4 const _ = require('lodash');
  5 +
5 const WHITE_LIST = [ 6 const WHITE_LIST = [
6 '/3party/check', 7 '/3party/check',
7 '/3party/check/submit', 8 '/3party/check/submit',
@@ -27,8 +28,7 @@ module.exports = (req, res, next) => { @@ -27,8 +28,7 @@ module.exports = (req, res, next) => {
27 } 28 }
28 29
29 if (req.xhr) { 30 if (req.xhr) {
30 - return res.json({  
31 - code: 400, 31 + return res.status(510).json({
32 data: {refer: limitAPI} 32 data: {refer: limitAPI}
33 }); 33 });
34 } 34 }
@@ -26,9 +26,9 @@ function isNormalSpider(userAgent) { @@ -26,9 +26,9 @@ function isNormalSpider(userAgent) {
26 26
27 module.exports = (limiter, policy) => { 27 module.exports = (limiter, policy) => {
28 const ua = limiter.req.header('User-Agent'); 28 const ua = limiter.req.header('User-Agent');
29 - const synchronizeKey = `wap:limiter:synchronize:${limiter.remoteIp}`; // 同步  
30 - const asynchronousKey = `wap:limiter:asynchronous:${limiter.remoteIp}`; // 异步  
31 - const spiderKey = `wap:limiter:spider:${limiter.remoteIp}`; // 异步 29 + const synchronizeKey = `pc:limiter:synchronize:${limiter.remoteIp}`; // 同步
  30 + const asynchronousKey = `pc:limiter:asynchronous:${limiter.remoteIp}`; // 异步
  31 + const spiderKey = `pc:limiter:spider:${limiter.remoteIp}`; // 异步
32 32
33 // 正常蜘蛛直接过 33 // 正常蜘蛛直接过
34 if (isNormalSpider(ua)) { 34 if (isNormalSpider(ua)) {
@@ -9,7 +9,7 @@ module.exports = (limiter, policy) => { @@ -9,7 +9,7 @@ module.exports = (limiter, policy) => {
9 res = limiter.res, 9 res = limiter.res,
10 next = limiter.next; // eslint-disable-line 10 next = limiter.next; // eslint-disable-line
11 11
12 - const key = `wap:limiter:faker:${limiter.remoteIp}`; 12 + const key = `pc:limiter:faker:${limiter.remoteIp}`;
13 13
14 if (req.header('X-Requested-With') === 'XMLHttpRequest') { 14 if (req.header('X-Requested-With') === 'XMLHttpRequest') {
15 cache.decrAsync(key, 1); 15 cache.decrAsync(key, 1);
@@ -2,16 +2,16 @@ @@ -2,16 +2,16 @@
2 2
3 const cache = global.yoho.cache.master; 3 const cache = global.yoho.cache.master;
4 const _ = require('lodash'); 4 const _ = require('lodash');
  5 +const config = global.yoho.config;
5 const logger = global.yoho.logger; 6 const logger = global.yoho.logger;
6 7
7 module.exports = (limiter, policy) => { 8 module.exports = (limiter, policy) => {
8 - // 和pc共用  
9 - const key = `pc:limiter:${limiter.remoteIp}`; 9 + const key = `${config.app}:limiter:${limiter.remoteIp}`;
10 10
11 return cache.getAsync(key).then((result) => { 11 return cache.getAsync(key).then((result) => {
12 logger.debug(key, result); 12 logger.debug(key, result);
13 13
14 - if (result && _.isNumber(result) && result !== -1) { 14 + if (result && _.isNumber(result)) {
15 return Promise.resolve(policy); 15 return Promise.resolve(policy);
16 } else { 16 } else {
17 return Promise.resolve(true); 17 return Promise.resolve(true);
@@ -27,12 +27,18 @@ module.exports = (limiter, policy) => { @@ -27,12 +27,18 @@ module.exports = (limiter, policy) => {
27 getOp[key] = cache.getAsync(ruleKeys[key]); 27 getOp[key] = cache.getAsync(ruleKeys[key]);
28 }); 28 });
29 29
  30 + getOp.human = cache.getAsync(`${config.app}:limiter:ishuman:${limiter.remoteIp}`);
  31 +
30 return Promise.props(getOp).then((results) => { 32 return Promise.props(getOp).then((results) => {
31 33
32 logger.debug(MAX_TIMES); 34 logger.debug(MAX_TIMES);
33 logger.debug(_.values(ruleKeys)); 35 logger.debug(_.values(ruleKeys));
34 logger.debug(results); 36 logger.debug(results);
35 37
  38 + if (results.human) { // 经过验证码之后1小时有效期内不再验证qps
  39 + return Promise.resolve(true);
  40 + }
  41 +
36 // 遍历限制规则,若满足返回相应处理策略, 否则页面访问次数加1 42 // 遍历限制规则,若满足返回相应处理策略, 否则页面访问次数加1
37 let operation = []; 43 let operation = [];
38 44
@@ -42,9 +48,10 @@ module.exports = (limiter, policy) => { @@ -42,9 +48,10 @@ module.exports = (limiter, policy) => {
42 if (!results[key]) { 48 if (!results[key]) {
43 operation.push(cache.setAsync(cacheKey, 1, +key)); 49 operation.push(cache.setAsync(cacheKey, 1, +key));
44 } else if (+results[key] > +val) { 50 } else if (+results[key] > +val) {
  51 + logger.warn(`${config.app}:limiter:${limiter.remoteIp}`);
45 52
46 // ip限制1小时 53 // ip限制1小时
47 - operation.push(cache.setAsync(`pc:limiter:${limiter.remoteIp}`, 1, limiterIpTime)); 54 + operation.push(cache.setAsync(`${config.app}:limiter:${limiter.remoteIp}`, 1, limiterIpTime));
48 return Promise.resolve(policy); 55 return Promise.resolve(policy);
49 } else { 56 } else {
50 operation.push(cache.incrAsync(cacheKey, 1)); 57 operation.push(cache.incrAsync(cacheKey, 1));
@@ -49,6 +49,8 @@ $(document).ajaxError((event, xhr) => { @@ -49,6 +49,8 @@ $(document).ajaxError((event, xhr) => {
49 window.location.href = `/signin.html?refer=${encodeURIComponent(window.location.href)}`; 49 window.location.href = `/signin.html?refer=${encodeURIComponent(window.location.href)}`;
50 } 50 }
51 } 51 }
  52 + } else if (xhr.status === 510 && xhr.responseJSON.data && xhr.responseJSON.data.refer) {
  53 + window.location.href = xhr.responseJSON.data.refer;
52 } else if (xhr.status === 403 && xhr.responseJSON.code === 4403) { 54 } else if (xhr.status === 403 && xhr.responseJSON.code === 4403) {
53 tip.show(xhr.responseJSON.message); 55 tip.show(xhr.responseJSON.message);
54 setTimeout(function() { 56 setTimeout(function() {