captcha.js 3.6 KB
/**
 * Created by TaoHuang on 2016/6/18.
 */

'use strict';
const _ =require('lodash');

const captchaService = require('../models/captcha-img-service');
const gtestCaptcha = require('./gee-captcha');
const helpers = global.yoho.helpers;
const CAPTCHA = 'yoho4946abcdef#$%&!@';
const request = require('request');
const logger = global.yoho.logger;

// 对比函数
const _mustEqual = (req) => {
    let result = req.session.captcha && (req.body.verifyCode === req.session.captcha ||
        req.body.verifyCode === CAPTCHA);

    logger.info(`img captcha auth [${result ? 'success' : 'fail'}]`,
        `CLIENT [${req.body.verifyCode}] SERVER [${req.session.captcha}]`);

    return result;
};

// 中间件
const requiredAPI = (req, res, next) => {
    let count = req.session.captchaCount;

    if (count >= 4) {
        req.session.captcha = CAPTCHA;

        return res.json({
            code: 403,
            message: '该验证码已失效'
        });
    }

    req.session.captchaCount = count + 1;
    if (_mustEqual(req)) {
        return next();
    } else {
        return res.json({
            code: 400,
            message: '请将图形验证码翻转至正确方向'
        });
    }
};

// 重定向调用
const requiredPage = (req, res, next) => {
    let count = req.session.captchaCount;

    if (count >= 4) {
        req.session.captcha = CAPTCHA;

        return res.redirect(helpers.urlFormat('/passport/back/index'));
    }

    req.session.captchaCount = count + 1;
    if (_mustEqual(req)) {
        return next();
    } else {
        return res.redirect(helpers.urlFormat('/passport/back/index'));
    }
};

// 生成验证码
const generate = (req, res, next) => {
    captchaService.generateCaptcha().then((result) => {
        req.session.captcha = result.data.text;
        req.session.captchaCount = 0;

        if (result.code === 200) {
            return res.json({
                code: result.code,
                data: {
                    images: result.data.images
                }
            });
        } else {
            return res.json({
                code: result.code,
                message: result.message
            });
        }

    }).catch(next);
};

// 七牛验证码
const generateQiniu = (req, res, next) => {
    captchaService.generateCaptcha().then((result) => {
        req.session.captcha = result.data.text;
        req.session.captchaCount = 0;

        res.type('png');
        if (result.code === 200) {
            request(result.data.images).pipe(res);
        }

    }).catch(next);
};

// 端到端检查
const checkAPI = (req, res) => {
    let count = req.session.captchaCount;

    if (count >= 4) {
        req.session.captcha = CAPTCHA;

        return res.json({
            code: 403,
            message: '该验证码已失效'
        });
    }

    req.session.captchaCount = count + 1;
    if (_mustEqual(req)) {
        return res.json({
            code: 200,
            message: '验证成功'
        });
    } else {
        return res.json({
            code: 400,
            message: '请将图形验证码翻转至正确方向'
        });
    }
};

const required = (req, res, next) => {
    req.app.locals.pc = _.merge(req.app.locals.pc, {
        geetest: {
            validation: false
        }
    });

    let captchaAPI = _.get(req.app.locals.pc, 'geetest.validation', false) ? gtestCaptcha.requiredAPI : requiredAPI;

    if (req.body.loginType === 'password') {
        return captchaAPI(req, res, next);
    } else {
        return next();
    }
};

module.exports = {
    requiredAPI,
    requiredPage,
    generate,
    checkAPI,
    generateQiniu,
    required
};