首先介绍一下我的项目环境:springboot2.3版本+mysql+redis:
引入以下依赖:
<!--图片验证码-->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
在resources目录下添加DefaultKaptcha.xml的配置文件,文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
<property name="config">
<bean class="com.google.code.kaptcha.util.Config">
<constructor-arg type="java.util.Properties">
<props>
<prop key="kaptcha.border ">yes</prop>
<prop key="kaptcha.border.color">105,179,90</prop>
<prop key="kaptcha.textproducer.font.color">blue</prop>
<prop key="kaptcha.image.width">100</prop>
<prop key="kaptcha.image.height">50</prop>
<prop key="kaptcha.textproducer.font.size">27</prop>
<prop key="kaptcha.session.key">code</prop>
<prop key="kaptcha.textproducer.char.length">4</prop>
<prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>
<prop key="kaptcha.textproducer.char.string">0123456789ABCEFGHIJKLMNOPQRSTUVWXYZ</prop>
<prop key="kaptcha.obscurificator.impl">com.google.code.kaptcha.impl.WaterRipple</prop>
<!--下面两行是干扰线的配置-->
<prop key="kaptcha.noise.color">black</prop>
<prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.DefaultNoise</prop>
<prop key="kaptcha.background.clear.from">185,56,213</prop>
<prop key="kaptcha.background.clear.to">white</prop>
<prop key="kaptcha.textproducer.char.space">3</prop>
</props>
</constructor-arg>
</bean>
</property>
</bean>
</beans>
以下两行是干扰线的配置:
<prop key="kaptcha.noise.color">black</prop>
<prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.DefaultNoise</prop>
修改为如下配置可以去掉干扰线,图片验证码更加易读一些:
<prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.NoNoise</prop>
接下来就是生成验证码图片的接口了:
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private DefaultKaptcha defaultKaptcha;
/**
* 生成验证码
* @param response
* @throws IOException
*/
@GetMapping("/generateAuthCode")
public void generateAuthCode(HttpServletResponse response) throws IOException {
byte[] captchaChallengeAsJpeg = null;
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
//生产验证码字符串并保存到redis中
String authCode = defaultKaptcha.createText();
String authCodeKey = String.valueOf(System.currentTimeMillis());
log.info("authCode is:" + authCode + ",authCodeKey is:" + authCodeKey);
redisTemplate.opsForValue().set(authCodeKey, authCode, 5, TimeUnit.SECONDS);
//使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
BufferedImage challenge = defaultKaptcha.createImage(authCode);
ImageIO.write(challenge, "jpg", jpegOutputStream);
//定义response输出类型为image/jpeg类型,使用response输出流输出图片的byte数组
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setHeader("authCodeKey", authCodeKey);
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
ServletOutputStream responseOutputStream = response.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
}
简单的介绍下流程,首先生成随机验证码,再根据当前时间戳生成一个字符串,生成这个随机字符串告诉前端,前端在登录的时候再把这个随机字符串拿过来,就可以从redis中取出验证码的值了,这个和手机验证码一个道理。
非常感谢这位大佬的分享:https://blog.csdn.net/fengzyf/article/details/87925705