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

com.github.kaizen4j.shiro.captcha.DefaultCaptchaManager Maven / Gradle / Ivy

The newest version!
package com.github.kaizen4j.shiro.captcha;

import java.time.Duration;
import java.util.Objects;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.util.WebUtils;

/**
 * @author liuguowen
 */
public final class DefaultCaptchaManager {

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

    private static final String DEFAULT_CAPTCHA_COOKIE_NAME = "J-CAPTCHA";

    private static final String DEFAULT_CAPTCHA_KEY_FORMAT = "J:CAPTCHA:%s";

    private static final Long DEFAULT_EXPIRE_TIME_MILLIS = Duration.ofMinutes(5).toMillis();

    private Long expireMillis = DEFAULT_EXPIRE_TIME_MILLIS;

    private Class engineClazz;

    private CaptchaStore captchaStore;

    public DefaultCaptchaManager(Class engineClazz, CaptchaStore captchaStore) {
        this.engineClazz = engineClazz;
        this.captchaStore = captchaStore;
    }

    public DefaultCaptchaManager(CaptchaStore captchaStore) {
        this(SimpleCaptchaEngine.class, captchaStore);
    }

    public CaptchaEngine getCaptchaEngine() {
        try {
            return engineClazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 存储验证码
     *
     * @param request the {@link HttpServletRequest} to use
     * @param response the {@link HttpServletResponse} to use
     * @param captcha 验证码文本
     */
    public void store(HttpServletRequest request, HttpServletResponse response, String captcha) {
        Cookie cookie = new SimpleCookie(DEFAULT_CAPTCHA_COOKIE_NAME);
        // 设置为不能通过客户端脚本访问
        cookie.setHttpOnly(true);
        cookie.setSecure(request.isSecure());
        cookie.setMaxAge(-1);

        String captchaId = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
        cookie.setValue(captchaId);
        cookie.saveTo(request, response);

        // just for test
        request.setAttribute(DEFAULT_CAPTCHA_COOKIE_NAME, captcha);

        if (logger.isDebugEnabled()) {
            logger.debug("Store captcha [{}] with id [{}] expireMillis [{}]", captcha, captchaId, expireMillis);
        }
        captchaStore.save(getCacheKey(captchaId), captcha, expireMillis);
    }

    /**
     * 校验当前输入的验证码是否正确
     *
     * @param request the {@link HttpServletRequest} to use
     * @param response the {@link HttpServletResponse} to use
     * @param expected 输入的验证码
     * @return 校验通过返回true,同时清空验证码及 Cookie。
     */
    public boolean check(HttpServletRequest request, HttpServletResponse response, String expected) {
        javax.servlet.http.Cookie cookie = WebUtils.getCookie(request, DEFAULT_CAPTCHA_COOKIE_NAME);
        if (Objects.isNull(cookie)) {
            return Boolean.FALSE;
        }

        String captchaId = cookie.getValue();
        if (StringUtils.isBlank(captchaId)) {
            return Boolean.FALSE;
        }

        boolean isPassed = captchaStore.validate(getCacheKey(captchaId), expected);
        if (isPassed) {
            // remove cookie
            cookie.setMaxAge(0);
            response.addCookie(cookie);

            if (logger.isDebugEnabled()) {
                logger.debug("Validate captcha [{}] passed with id [{}]", expected, captchaId);
            }
        }
        return isPassed;
    }

    private String getCacheKey(String captchaId) {
        return String.format(DEFAULT_CAPTCHA_KEY_FORMAT, captchaId);
    }

    public CaptchaStore getCaptchaStore() {
        return captchaStore;
    }

    public Long getExpireMillis() {
        return expireMillis;
    }

    public void setExpireMillis(Long expireMillis) {
        this.expireMillis = expireMillis;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy