All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gitee.cliveyuan.tools.web.CaptchaTools Maven / Gradle / Ivy

There is a newer version: 4.0.6
Show newest version
package com.gitee.cliveyuan.tools.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gitee.cliveyuan.tools.Assert;
import com.gitee.cliveyuan.tools.IdTools;
import com.gitee.cliveyuan.tools.StringTools;
import com.gitee.cliveyuan.tools.VerifyCodeTools;
import com.gitee.cliveyuan.tools.bean.Captcha;
import com.gitee.cliveyuan.tools.bean.CaptchaCodeResult;
import com.gitee.cliveyuan.tools.bean.CaptchaRequest;
import com.gitee.cliveyuan.tools.bean.CaptchaV2;
import com.gitee.cliveyuan.tools.bean.CaptchaValidate;
import com.gitee.cliveyuan.tools.enums.CaptchaGenerateType;
import com.gitee.cliveyuan.tools.enums.CaptchaType;
import com.gitee.cliveyuan.tools.exception.CaptchaException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Objects;


/**
 * 验证码工具类
 *
 * @author clive
 * Created on 2018-07-27
 */
public class CaptchaTools {

    private final static Logger logger = LoggerFactory.getLogger(CaptchaTools.class);

    public final static String DEFAULT_CAPTCHA_NAME = "CAPTCHA_NAME";
    public final static int DEFAULT_CAPTCHA_LENGTH = 5;
    public final static int DEFAULT_CAPTCHA_WIDTH = 300;
    public final static int DEFAULT_CAPTCHA_HEIGHT = 100;

    private CaptchaTools() {
    }

    /**
     * 验证验证码
     * 验证码正确不抛异常, 错误抛CaptchaException异常
     *
     * @param inputCaptcha 输入的验证码
     * @param request      请求
     * @deprecated CaptchaTools#validate(CaptchaValidate captchaValidate)
     */
    @Deprecated
    public static void validate(Captcha inputCaptcha, HttpServletRequest request) {
        validate(inputCaptcha, request, DEFAULT_CAPTCHA_NAME);
    }

    /**
     * 验证验证码
     * 验证码正确不抛异常, 错误抛CaptchaException异常
     *
     * @param inputCaptcha 输入的验证码
     * @param request      请求
     * @param captchaName  验证码session名
     * @see CaptchaTools#validate(CaptchaValidate captchaValidate)
     * @deprecated CaptchaTools#validate(CaptchaValidate captchaValidate)
     */
    @Deprecated
    public static void validate(Captcha inputCaptcha, HttpServletRequest request, String captchaName) {
        logger.debug("CaptchaTools.validate: inputCaptcha={}, captchaName={}", inputCaptcha, captchaName);
        Assert.notNull(request, "request is required");
        HttpSession session = request.getSession();
        if (Objects.isNull(inputCaptcha)) throw CaptchaException.captchaIsNull();
        if (StringTools.isBlank(inputCaptcha.getCaptchaId())) throw CaptchaException.idIsEmpty();
        if (StringTools.isBlank(inputCaptcha.getCaptchaValue())) throw CaptchaException.valueIsEmpty();
        if (StringTools.isBlank(captchaName)) captchaName = DEFAULT_CAPTCHA_NAME;

        inputCaptcha.setCaptchaValue(inputCaptcha.getCaptchaValue().toLowerCase());
        String captchaStr = (String) session.getAttribute(captchaName);
        if (StringTools.isBlank(captchaStr)) throw CaptchaException.notInSession();

        Captcha captcha = JSONObject.parseObject(captchaStr, Captcha.class);
        if (Objects.isNull(captcha)) throw CaptchaException.parseJsonError();
        logger.debug("CaptchaTools.validate:  输入的验证码: {}, 生成的验证码: {}", inputCaptcha, captcha);
        if (!Objects.equals(inputCaptcha, captcha)) throw CaptchaException.notMatch();
        logger.debug("CaptchaTools.validate: matched");
    }

    /**
     * 校验验证码 v2
     * 

* 验证码正确不抛异常, 错误抛CaptchaException异常 * * @param captchaValidate */ public static boolean validate(CaptchaValidate captchaValidate) { logger.debug("CaptchaTools.validate: captchaValidate={}", captchaValidate); try { Assert.notNull(captchaValidate, "captchaValidate is null"); HttpServletRequest request = captchaValidate.getRequest(); CacheManager cacheManager = captchaValidate.getCacheManager(); String cacheNamespace = captchaValidate.getCacheNamespace(); Assert.notNull(captchaValidate.getGenerateType(), "generateType is null"); if (CaptchaGenerateType.SESSION.equals(captchaValidate.getGenerateType())) { Assert.notNull(request, "request is null"); } else if (CaptchaGenerateType.CACHE.equals(captchaValidate.getGenerateType())) { Assert.notNull(cacheManager, "cacheManager is null"); Assert.notNull(cacheNamespace, "cacheNamespace is null"); } CaptchaV2 inputCaptcha = captchaValidate.getCaptcha(); String captchaName = captchaValidate.getName(); if (Objects.isNull(inputCaptcha)) throw CaptchaException.captchaIsNull(); if (StringTools.isBlank(inputCaptcha.getId())) throw CaptchaException.idIsEmpty(); if (StringTools.isBlank(inputCaptcha.getValue())) throw CaptchaException.valueIsEmpty(); if (StringTools.isBlank(captchaName)) captchaName = DEFAULT_CAPTCHA_NAME; inputCaptcha.setValue(inputCaptcha.getValue().toLowerCase()); CaptchaV2 captcha = null; if (CaptchaGenerateType.SESSION.equals(captchaValidate.getGenerateType())) { captcha = getFromSession(captchaValidate, captchaName); } else if (CaptchaGenerateType.CACHE.equals(captchaValidate.getGenerateType())) { captcha = getFromCache(captchaValidate, captchaName); } if (Objects.isNull(captcha)) throw CaptchaException.parseJsonError(); logger.debug("CaptchaTools.validate: 输入的验证码: {}, 生成的验证码: {}", inputCaptcha, captcha); // 移除验证码 removeCaptcha(captchaValidate, captchaName); captcha.setValue(captcha.getValue().toLowerCase()); // fix 大小写不匹配问题 if (!Objects.equals(inputCaptcha, captcha)) { throw CaptchaException.notMatch(); } } catch (CaptchaException e) { if (captchaValidate.isThrowExceptionWhenError()) { throw e; } logger.info("CaptchaTools.validate: ERROR code={}, msg={}", e.getCode(), e.getMessage()); return false; } logger.debug("CaptchaTools.validate: matched"); return true; } /** * 生成验证码 * * @param request 请求 * @param response 响应 * @param id 验证码id 初始生成时可不传 */ @Deprecated public static void generate( HttpServletRequest request, HttpServletResponse response, String id ) { generate(request, response, id, DEFAULT_CAPTCHA_NAME); } /** * 生成验证码 * * @param request 请求 * @param response 响应 * @param id 验证码id 初始生成时可不传 * @param captchaName 验证码session名 */ @Deprecated public static void generate( HttpServletRequest request, HttpServletResponse response, String id, String captchaName ) { generate(request, response, id, captchaName, DEFAULT_CAPTCHA_LENGTH); } /** * 生成验证码 * * @param request 请求 * @param response 响应 * @param id 验证码id 初始生成时可不传 * @param captchaName 验证码session名 * @param length 验证码字符长度 */ @Deprecated public static void generate( HttpServletRequest request, HttpServletResponse response, String id, String captchaName, int length ) { generate(request, response, id, captchaName, length, DEFAULT_CAPTCHA_WIDTH, DEFAULT_CAPTCHA_HEIGHT); } /** * 生成验证码 * * @param request 请求 * @param response 响应 * @param id 验证码id 初始生成时可不传 * @param captchaName 验证码session名 * @param length 验证码字符长度 * @param width 验证码图片宽度 单位像素 * @param height 验证码图片搞定 单位像素 * @see CaptchaTools#generate(CaptchaRequest captchaRequest) * @deprecated see CaptchaTools#generate(CaptchaRequest captchaRequest) */ @Deprecated public static void generate( HttpServletRequest request, HttpServletResponse response, String id, String captchaName, int length, int width, int height ) { logger.debug("CaptchaTools.generate id={}, length={}", id, length); try { System.setProperty("java.awt.headless", "true"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); // 生成随机字串 String verifyCode = VerifyCodeTools.generateVerifyCode(length); // 存入会话session HttpSession session = request.getSession(true); if (StringTools.isBlank(id)) { id = IdTools.randomShortUUID(); } Captcha captcha = new Captcha(id, verifyCode.toLowerCase()); session.setAttribute(captchaName, JSON.toJSONString(captcha)); // 生成图片 VerifyCodeTools.outputImage(width, height, response.getOutputStream(), verifyCode); logger.debug("CaptchaTools.generate: success -> {}", captcha); } catch (Exception e) { logger.error("generate error", e); } } /** * 生成验证码 v2 * * @param captchaRequest captchaRequest */ public static void generate(CaptchaRequest captchaRequest) { logger.debug("CaptchaTools.generate captchaRequest={}", captchaRequest); Assert.notNull(captchaRequest, "captchaRequest is null"); HttpServletResponse response = captchaRequest.getResponse(); HttpServletRequest request = captchaRequest.getRequest(); CacheManager cacheManager = captchaRequest.getCacheManager(); String cacheNamespace = captchaRequest.getCacheNamespace(); Assert.notNull(response, "response is null"); Assert.notNull(captchaRequest.getGenerateType(), "generateType is null"); if (CaptchaGenerateType.SESSION.equals(captchaRequest.getGenerateType())) { Assert.notNull(request, "request is null"); } else if (CaptchaGenerateType.CACHE.equals(captchaRequest.getGenerateType())) { Assert.notNull(cacheManager, "cacheManager is null"); Assert.notNull(cacheNamespace, "cacheNamespace is null"); } int length = captchaRequest.getLength(); int width = captchaRequest.getWidth(); int height = captchaRequest.getHeight(); if (length <= 0) { length = DEFAULT_CAPTCHA_LENGTH; } if (width <= 0) { width = DEFAULT_CAPTCHA_WIDTH; } if (height <= 0) { height = DEFAULT_CAPTCHA_HEIGHT; } try { System.setProperty("java.awt.headless", "true"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); // 生成随机字串 CaptchaCodeResult captchaCodeResult = CaptchaCodeResult.builder().build(); switch (captchaRequest.getCaptchaType()) { case LETTER_NUM: captchaCodeResult = VerifyCodeTools.generateLetterNumVerifyCode(length); break; case MATH_ADD: captchaCodeResult = VerifyCodeTools.generateMathAddVerifyCode(captchaRequest.getMathAddStart(), captchaRequest.getMathAddEnd()); break; } String id = captchaRequest.getId(); if (StringTools.isBlank(id)) { id = IdTools.randomShortUUID(); } CaptchaV2 captcha = new CaptchaV2(id, captchaCodeResult.getVerifyContent()); if (CaptchaGenerateType.SESSION.equals(captchaRequest.getGenerateType())) { saveToSession(captchaRequest, captcha); } else if (CaptchaGenerateType.CACHE.equals(captchaRequest.getGenerateType())) { saveToCache(captchaRequest, captcha); } // 生成图片 VerifyCodeTools.outputImage(width, height, response.getOutputStream(), captchaCodeResult.getCaptchaContent(), !CaptchaType.MATH_ADD.equals(captchaRequest.getCaptchaType())); logger.debug("CaptchaTools.generate: success -> {}", captcha); } catch (Exception e) { logger.error("generate error", e); } } private static String getKey(String captchaName, String id) { return String.format("%s_%s", captchaName, id); } private static void saveToSession(CaptchaRequest captchaRequest, CaptchaV2 captcha) { HttpSession session = captchaRequest.getRequest().getSession(true); String name = captchaRequest.getName(); if (Objects.isNull(name)) { name = DEFAULT_CAPTCHA_NAME; } session.setAttribute(getKey(name, captcha.getId()), JSON.toJSONString(captcha)); } private static void saveToCache(CaptchaRequest captchaRequest, CaptchaV2 captcha) { CacheManager cacheManager = captchaRequest.getCacheManager(); Cache cache = cacheManager.getCache(captchaRequest.getCacheNamespace()); String name = captchaRequest.getName(); if (Objects.isNull(name)) { name = DEFAULT_CAPTCHA_NAME; } cache.put(getKey(name, captcha.getId()), captcha); } private static CaptchaV2 getFromSession(CaptchaValidate captchaValidate, String captchaName) { HttpSession session = captchaValidate.getRequest().getSession(true); String captchaStr = (String) session.getAttribute(getKey(captchaName, captchaValidate.getCaptcha().getId())); if (StringTools.isBlank(captchaStr)) throw CaptchaException.notInSession(); return JSONObject.parseObject(captchaStr, CaptchaV2.class); } private static CaptchaV2 getFromCache(CaptchaValidate captchaValidate, String captchaName) { CacheManager cacheManager = captchaValidate.getCacheManager(); Cache cache = cacheManager.getCache(captchaValidate.getCacheNamespace()); Cache.ValueWrapper valueWrapper = cache.get(getKey(captchaName, captchaValidate.getCaptcha().getId())); if (Objects.nonNull(valueWrapper)) { return (CaptchaV2) valueWrapper.get(); } return null; } private static void removeCaptcha(CaptchaValidate captchaValidate, String captchaName) { if (CaptchaGenerateType.SESSION.equals(captchaValidate.getGenerateType())) { removeFromSession(captchaValidate, captchaName); } else if (CaptchaGenerateType.CACHE.equals(captchaValidate.getGenerateType())) { removeFromCache(captchaValidate, captchaName); } } private static void removeFromSession(CaptchaValidate captchaValidate, String captchaName) { HttpSession session = captchaValidate.getRequest().getSession(true); session.removeAttribute(getKey(captchaName, captchaValidate.getCaptcha().getId())); } private static void removeFromCache(CaptchaValidate captchaValidate, String captchaName) { CacheManager cacheManager = captchaValidate.getCacheManager(); Cache cache = cacheManager.getCache(captchaValidate.getCacheNamespace()); cache.evict(getKey(captchaName, captchaValidate.getCaptcha().getId())); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy