limiter.js 1.14 KB

'use strict';

const cache = global.yoho.cache.master;
const _ = require('lodash');
const logger = global.yoho.logger;

module.exports = (req, res, next) => {
    let remoteIp = req.get('X-Forwarded-For') || '';

    if (remoteIp.indexOf(',') > 0) {
        let arr = remoteIp.split(',');
        remoteIp = arr[0];
    }

    if (remoteIp &&  !_.get(req.app.locals, 'pc.sys.noLimiter')) {   // 判断获取remoteIp成功,并且开关未关闭
        let key = `pc:limiter:${remoteIp}`;

        logger.debug(`request limiter key=${key}`);

        cache.getAsync(key).then(result => {
            if (result && _.isNumber(result)) {
                if (result > 30) {          // 判断 qps
                    res.status(403).end();
                } else {
                    cache.incrAsync(key, 1); // qps + 1
                    next();
                }
            } else {
                cache.setAsync(key, 1, 1);  // 设置key,1s失效
                next();
            }
        }).catch(e => {
            logger.error(`request limiter get key[${key}] from cache error.`, e);
            next();
        });
    } else {
        next();
    }
};