【Java】EasyCaptcha 封装验证码接口
依赖坐标:
<dependency> <groupId>com.github.whvcse</groupId> <artifactId>easy-captcha</artifactId> <version>1.6.2</version> </dependency>
参考EasyCaptcha官方文档:
https://gitcode.net/mirrors/whvcse/easycaptcha?utm_source=csdn_github_accelerator
先上代码:
package cn.cloud9.server.test.controller; import cn.cloud9.server.struct.common.BaseController; import cn.cloud9.server.struct.response.NoApiResult; import cn.cloud9.server.struct.spring.SpringContextHolder; import cn.cloud9.server.struct.util.IpUtil; import cn.cloud9.server.test.model.CaptchaParam; import com.wf.captcha.SpecCaptcha; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.web.bind.annotation.*; import java.awt.*; import java.io.IOException; import java.util.Objects; import java.util.concurrent.TimeUnit; /** * @author OnCloud9 * @description 验证码测试类 * @project tt-server * @date 2022年11月07日 下午 09:11 */ @RestController @RequestMapping("/test/captcha") public class CaptchaController extends BaseController { private static final String captchaKey = "CAPTCHA"; private static final String separator = "@"; private static final StringRedisTemplate redisTemplate = SpringContextHolder.getBean(StringRedisTemplate.class); private static final ValueOperations<String, String> valOps = redisTemplate.opsForValue(); /** * 获取验证码图片 * @param param 验证码生成参数对象 * @throws IOException IO异常 */ @NoApiResult @GetMapping("get") public void createCaptcha(@ModelAttribute CaptchaParam param) throws IOException { /* 三个参数分别为宽、高、位数 */ SpecCaptcha specCaptcha = new SpecCaptcha(param.getWidth(), param.getHeight(), param.getLength()); /* 设置字体 */ specCaptcha.setFont(new Font(param.getFontName(), param.getFontStyle(), param.getFontSize())); // 有默认字体,可以不用设置 /* 设置类型,纯数字、纯字母、字母数字混合 */ specCaptcha.setCharType(param.getCharType()); /* 设置验证码 */ final String text = specCaptcha.text().toUpperCase(); final String ipAddr = IpUtil.getIpAddr(request); final String key = captchaKey + separator + ipAddr; final boolean isUseRedis = param.isUseRedis(); if (isUseRedis) valOps.set(key, text, 5 * 60, TimeUnit.SECONDS); else request.getSession().setAttribute(key, text); /* 输出验证码图片 */ final boolean isBase64 = param.isBase64(); if (isBase64) { final String base64 = specCaptcha.toBase64(); response.getWriter().write(base64); } else { /* 设置请求头为输出图片类型 */ response.setContentType("image/gif"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); /* 输出验证码图片 */ specCaptcha.out(response.getOutputStream()); } } /** * 验证图片验证码 (可以是验证码失效,错误,这里简单判断为true和false) * @param verifyCode 图片验证码 * @param useRedis 是否使用Redis缓存 * @return 验证结果 */ @PostMapping("verify") public boolean verifyCaptcha(@RequestParam String verifyCode, @RequestParam(required = false) boolean useRedis) { String storeCode = null; final String ipAddr = IpUtil.getIpAddr(request); final String key = captchaKey + separator + ipAddr; if (useRedis) { storeCode = valOps.get(key); } else { final Object attribute = request.getSession().getAttribute(key); storeCode = Objects.isNull(attribute) ? "" : String.valueOf(attribute); } return verifyCode.equalsIgnoreCase(storeCode); } }
参数对象:
package cn.cloud9.server.test.model; import com.wf.captcha.base.Captcha; import lombok.Data; import java.awt.*; /** * @author OnCloud9 * @description * @project tt-server * @date 2022年11月25日 下午 08:50 */ @Data public class CaptchaParam { /* 设置宽度,高度,码数长度 */ private int width = 200; private int height = 80; private int length = 6; /* 字体设置 */ private String fontName = "Verdana"; private int fontStyle = Font.PLAIN; private int fontSize = 32; /** * 验证码字符类型设置 * TYPE_DEFAULT = 1; * TYPE_ONLY_NUMBER = 2; * TYPE_ONLY_CHAR = 3; * TYPE_ONLY_UPPER = 4; * TYPE_ONLY_LOWER = 5; * TYPE_NUM_AND_UPPER = 6; */ private int charType = Captcha.TYPE_ONLY_NUMBER; /* 是否使用base64 默认不使用 */ private boolean base64 = false; /* 是否使用Redis 默认不使用 */ private boolean useRedis = false; }
我想,其实就算是前后端分离项目,也一样可以用Session存验证码的
手动设置验证码生成参数,前端投送参数来决定验证码的生成和存储
这里多加一个flag判断是否使用Redis存储,接口就更灵活些
设置为true时,可以检查是否走Redis了
测试校验接口是否走Redis
使用Base64编码: