不使用 Session 的 SpringBoot kaptcha 图片验证码校验

tech2025-06-18  3

SpringBoot 整合 kaptcha 进行图片验证码人机校验,用token+redis替代session完成验证。

基本原理图实现代码1. 导入kaptcha2. 添加kaptcha配置常用配置配置类配置 先上效果图实现代码

基本原理图

实现代码

1. 导入kaptcha

在porm.xml配置文件添加依赖,并Reimport

<dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </dependency>

2. 添加kaptcha配置

常用配置

属性详情默认值kaptcha.border图片边框,合法值:yes , no"yes"kaptcha.border.color边框颜色,合法值: "255,255,255" 或者 "255,255,255,Alpha" 或者 java.awt.Color 包所有的颜色名称:blue、green、yellow (Alpha的取值范围0-255)"black"kaptcha.border.thickness边框厚度,合法值:>0"1"kaptcha.textproducer.char.string文本集合,验证码值从此集合中获取"abcde2345678gfynmnpwx"kaptcha.textproducer.char.length验证码长度"5"kaptcha.textproducer.font.names文本字体"Arial,Courier"kaptcha.textproducer.font.size字体大小"40"kaptcha.textproducer.char.space字符间隔"2""kaptcha.noise.color"干扰颜色 合法值同 kaptcha.border.color"black""kaptcha.obscurificator.impl"遮光罩: 水纹com.google.code.kaptcha.impl.WaterRipple鱼眼com.google.code.kaptcha.impl.FishEyeGimpy阴影com.google.code.kaptcha.impl.ShadowGimpy"com.google.code.kaptcha.impl.WaterRipple""kaptcha.image.width"图片宽"200""kaptcha.image.height"图片高"50"

配置类配置

@Configuration public class kaptchaConfig { @Bean public DefaultKaptcha getDefaultKaptcha(){ DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); Properties properties = new Properties(); properties.setProperty("kaptcha.border.color","34,53,193,155"); properties.setProperty("kaptcha.border.thickness","5"); properties.setProperty("kaptcha.textproducer.char.length","6"); properties.setProperty("kaptcha.textproducer.font.names","宋体,Arial,Courier"); properties.setProperty("kaptcha.noise.color","blue"); Config config = new Config(properties); defaultKaptcha.setConfig(config); return defaultKaptcha; } }

先上效果图

获取token 使用token获取验证码 redis这边

实现代码

获取token public ResultVO getToken() { //生成唯一字符串作为token String token = UUID.randomUUID().toString(); //存入redis redisTemplate.opsForValue().set(token,new JSONObject().toJSONString()); return ResultVOUtil.succese(token); } 获取验证码 public void getVerify(String token, HttpServletResponse response) { //判断token是否存在redis,不存在则重新生成 if(!redisTemplate.hasKey(token)){ throw new LoginException(ResultEnum.TOKEN_NOT_NULL.getCode(),ResultEnum.TOKEN_NOT_NULL.getMsg()); } //生成验证码字符 String text = producer.createText(); //将验证码字符序列化存入redis redisTemplate.opsForValue().set(token,JsonUtil.add(redisTemplate.opsForValue().get(token),RedisMapEnum.VERIFY_CODE.getKey(),text)); //使用验证码字符生成验证码图片 BufferedImage image = producer.createImage(text); //设置头,输出格式与不缓存 response.setContentType("image/jpeg"); response.setHeader("Cache-Control","no-cache"); ServletOutputStream outputStream = response.getOutputStream(); //使用ImageIO向前端输出图片 ImageIO.write(image,"jpeg",outputStream); } 登录 public ResultVO login(LoginForm loginForm) { String token = loginForm.getToken(); //验证验证码是否正确 if(!checkVerifyCode(token,loginForm.getVerifyCode())){ return ResultVOUtil.error(ResultEnum.VERIFY_ERROR.getCode(),ResultEnum.VERIFY_ERROR.getMsg()); } //验证账号密码 ManagerDao managerDao = managerService.findOne(loginForm.getManagerId()); if(managerDao == null || managerDao.getManagerPwd() != loginForm.getManagerpwd()){ return ResultVOUtil.error(ResultEnum.LOGIN_ERROR.getCode(),ResultEnum.LOGIN_ERROR.getMsg()); } //登录成功,将权限信息存入redis redisTemplate.opsForValue().set(token,JsonUtil.add(redisTemplate.opsForValue().get(token),RedisMapEnum.MANAGER_WEIGH.getKey(),managerDao.getJurisdictionDao().getManagerWeigh())); return ResultVOUtil.succese(); } 验证验证码字符的代码 private boolean checkVerifyCode(String token, String verifyCode){ //从redis取出验证码字符进行比对 String code = JsonUtil.get(redisTemplate.opsForValue().get(token),RedisMapEnum.VERIFY_CODE.getKey()); if(code == null || code != verifyCode){ return false; } return true; } JsonUtil 代码 //这里用到了alibaba.fastjson包 public class JsonUtil { public static String add(String json,String key, Object value){ JSONObject jsonObject = JSON.parseObject(json); jsonObject.put(key,value); return jsonObject.toJSONString(); } public static String get(String json, String key){ JSONObject jsonObject = JSON.parseObject(json); return jsonObject.getString(key); } }
最新回复(0)