【Java】EasyCaptcha 封装验证码接口
依赖坐标:
1 2 3 4 5 | < dependency > < groupId >com.github.whvcse</ groupId > < artifactId >easy-captcha</ artifactId > < version >1.6.2</ version > </ dependency > |
参考EasyCaptcha官方文档:
1 | https: //gitcode.net/mirrors/whvcse/easycaptcha?utm_source=csdn_github_accelerator |
先上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | 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); } } |
参数对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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编码:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!
2021-11-25 【Java】java.util.ConcurrentModificationException
2021-11-25 【Git】GithubDesktop 忽略文件无法忽略BUG