SpringBoot 整合Kaptcha图形验证码
1. pom.xml Maven依赖
<dependency>
<groupId>com.google.code.kaptcha</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
2. kaptcha配置类
package com.ruhuanxingyun.shiro.demo.config;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
* @description: 验证码配置类
* @author: ruphie
* @date: Create in 2019/12/16 12:25
* @company: ruhuanxingyun
*/
@Configuration
public class KaptchaConfig {
@Bean
public DefaultKaptcha defaultKaptcha() {
Properties properties = new Properties();
// 图片边框,默认有
//properties.setProperty(Constants.KAPTCHA_BORDER, "yes");
// 边框颜色,默认黑色
//properties.setProperty(Constants.KAPTCHA_BORDER_COLOR, "105,179,90");
// 干扰线颜色,默认黑色
//properties.setProperty(Constants.KAPTCHA_NOISE_COLOR, "black");
// 干扰线实现类
// properties.setProperty(Constants.KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.DefaultNoise");
// 文本集合,验证码值从此集合中拿
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "23456789abcefghjkmnpqrstuvwxyz");
// 验证码长度
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
// 文本间隔
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "4");
// 字体
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES, "宋体,楷体,微软雅黑");
// 字体颜色,默认黑色
//properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
// 字体大小
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "28");
// 背景颜色渐变开始色
properties.setProperty(Constants.KAPTCHA_BACKGROUND_CLR_FROM, "196,196,196");
// 背景颜色渐变结束色,默认白色
//properties.setProperty(Constants.KAPTCHA_BACKGROUND_CLR_TO, "white");
// 图片宽度
properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "120");
// 图片高度
properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "35");
// 图片样式
properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
Config config = new Config(properties);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
3. 生成图形验证码
@GetMapping("/kaptcha")
@ApiOperation("/生成图形验证码")
public void kaptcha(HttpServletRequest request,
HttpServletResponse response) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 生成文本验证码
String text = defaultKaptcha.createText();
// 获取唯一性IP标识
String ipAddress = AddressUtils.getIpAddr(request);
redisTemplate.opsForValue().set(RedisConstant.CAPTCHA_PREFIX + ipAddress, text);
BufferedImage bufferedImage = defaultKaptcha.createImage(text);
try {
ImageIO.write(bufferedImage, "jpg", baos);
} catch (IOException e) {
e.printStackTrace();
response.sendError(HttpStatus.NOT_FOUND.value());
return;
}
// 禁止浏览器缓存数据
response.setHeader(HttpHeaders.CACHE_CONTROL, "no-store");
response.setHeader(HttpHeaders.PRAGMA, "no-cache");
response.setDateHeader(HttpHeaders.EXPIRES, 0);
response.setContentType("image/jpeg");
// 使用response响应流输出图片
ServletOutputStream sos = response.getOutputStream();
sos.write(baos.toByteArray());
sos.flush();
sos.close();
}
package com.ruhuanxingyun.demo.utils; import javax.servlet.http.HttpServletRequest; import java.net.InetAddress; import java.net.UnknownHostException; /** * @description: IP地址工具类 * @author: ruphie * @date: Create in 2019/12/23 17:07 * @company: ruhuanxingyun */ public class AddressUtils { /** * 获取IP * * @param request 请求对象 * @return ipAddress */ public static String getIpAddr(HttpServletRequest request) { String ipAddress = request.getHeader("x-forwarded-for"); if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("WL-Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); if ("127.0.0.1".equals(ipAddress) || "0:0:0:0:0:0:0:1".equals(ipAddress)) { //根据网卡取本机配置的IP InetAddress inet = null; try { inet = InetAddress.getLocalHost(); } catch (UnknownHostException e) { return null; } ipAddress = inet.getHostAddress(); } } // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割,"***.***.***.***".length() = 15 if (ipAddress != null && ipAddress.length() > 15 && ipAddress.indexOf(',') > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(',')); } return ipAddress; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗