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

cn.cliveyuan.tools.web.CaptchaTools Maven / Gradle / Ivy

The newest version!
package cn.cliveyuan.tools.web;

import cn.cliveyuan.tools.common.AssertTools;
import cn.cliveyuan.tools.common.IdTools;
import cn.cliveyuan.tools.common.StringTools;
import cn.cliveyuan.tools.web.bean.Captcha;
import cn.cliveyuan.tools.web.bean.CaptchaCodeResult;
import cn.cliveyuan.tools.web.bean.CaptchaGenerateType;
import cn.cliveyuan.tools.web.bean.CaptchaRequest;
import cn.cliveyuan.tools.web.bean.CaptchaType;
import cn.cliveyuan.tools.web.bean.CaptchaValidate;
import cn.cliveyuan.tools.web.exception.CaptchaException;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
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() {
    }

    /**
     * 校验验证码 v2
     * 

* 验证码正确不抛异常, 错误抛CaptchaException异常 * * @param captchaValidate captchaValidate */ public static boolean validate(CaptchaValidate captchaValidate) { logger.debug("CaptchaTools.validate: captchaValidate={}", captchaValidate); try { AssertTools.notNull(captchaValidate, "captchaValidate is null"); HttpServletRequest request = captchaValidate.getRequest(); CacheManager cacheManager = captchaValidate.getCacheManager(); String cacheNamespace = captchaValidate.getCacheNamespace(); AssertTools.notNull(captchaValidate.getGenerateType(), "generateType is null"); if (CaptchaGenerateType.SESSION.equals(captchaValidate.getGenerateType())) { AssertTools.notNull(request, "request is null"); } else if (CaptchaGenerateType.CACHE.equals(captchaValidate.getGenerateType())) { AssertTools.notNull(cacheManager, "cacheManager is null"); AssertTools.notNull(cacheNamespace, "cacheNamespace is null"); } Captcha 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()); Captcha 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; } /** * 生成验证码 v2 * * @param captchaRequest captchaRequest */ public static void generate(CaptchaRequest captchaRequest) { logger.debug("CaptchaTools.generate captchaRequest={}", captchaRequest); AssertTools.notNull(captchaRequest, "captchaRequest is null"); HttpServletResponse response = captchaRequest.getResponse(); HttpServletRequest request = captchaRequest.getRequest(); CacheManager cacheManager = captchaRequest.getCacheManager(); String cacheNamespace = captchaRequest.getCacheNamespace(); AssertTools.notNull(response, "response is null"); AssertTools.notNull(captchaRequest.getGenerateType(), "generateType is null"); if (CaptchaGenerateType.SESSION.equals(captchaRequest.getGenerateType())) { AssertTools.notNull(request, "request is null"); } else if (CaptchaGenerateType.CACHE.equals(captchaRequest.getGenerateType())) { AssertTools.notNull(cacheManager, "cacheManager is null"); AssertTools.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(); } Captcha captcha = new Captcha(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, Captcha 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, Captcha 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 Captcha 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, Captcha.class); } private static Captcha 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 (Captcha) 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