validateCode.js 2.67 KB
/**
 * 验证码中间件
 * @author feng.chen<feng.chen@yoho.cn>
 * @date 2017/03/23
 */

'use strict';
const _ = require('lodash');
const config = global.yoho.config;
const co = Promise.coroutine;
const cache = global.yoho.cache;
const log = global.yoho.logger;
const geetest = require('./geetest');
const captcha = require('./captcha');

/**
 * 验证验证码
 */
const check = (req, res, next) => {
    let testCode = req.body.yohobuy;

    if (testCode === config.testCode) {
        return next();
    }

    // 默认取配置总开关来决定是否展示验证码
    req.yoho.captchaShow = !_.get(req.app.locals.wap, 'close.loginValidation', false);

    co(function* () {
        // 如果是账号密码登录,那么需要检查是否登录失败过,登录失败过展示验证码
        if (req.path === '/passport/login/auth') {
            let hasErrorLog = yield cache.get(`loginErrorIp:${req.yoho.clientIp}`);

            log.info(`Check clientip ${req.yoho.clientIp} status is ` + hasErrorLog);

            if (hasErrorLog) {
                req.yoho.captchaShow = true;
            } else {
                req.yoho.captchaShow = false;
            }
        }

        return req.yoho.captchaShow;
    })().catch(function() {
        // memcache 不可用,展示验证码
        req.yoho.captchaShow = true;
        return req.yoho.captchaShow;
    }).then(function() {
        // 不是账号密码登录,直接根据配置总开关决定是否需要展示验证码
        if (!req.yoho.captchaShow) {
            return next();
        }

        // 使用极验证
        let useGeetest = !_.get(req.app.locals.wap, 'geetest.validation', false);

        // 某次请求极验证调用注册失败,强制使用自有图形验证码
        if (req.session.useYohoCaptcha) {
            useGeetest = false;
        }

        return (useGeetest ? geetest : captcha).validate(req, res, next);
    });
};

/**
 * 加载验证码
 */
const load = (req, res, next) => {
    res.locals.useGeetest = !_.get(req.app.locals.wap, 'geetest.validation', false); // 使用极验证
    if (_.has(res, 'locals.loadJs')) {
        res.locals.loadJs.push({
            src: global.yoho.config.geetestJs
        });
    } else {
        res.locals.loadJs = [
            {
                src: global.yoho.config.geetestJs
            }
        ];
    }
    return next();
};

/**
 * 测试使用,上线前删除
 */
const forTest = (req, res, next) => {
    if (req.query.image) {
        _.set(req, 'app.locals.wap.geetest.validation', true);
    } else {
        _.set(req, 'app.locals.wap.geetest.validation', false);
    }
    return next();
};

module.exports = {
    check,
    load,
    forTest
};