springboot中使用kaptcha验证码
maven依赖
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
kaptcha配置
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;
@Configuration
public class KaptchaConfig {
@Bean
public DefaultKaptcha getDefaultKaptcha() {
DefaultKaptcha kaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 图片边框
properties.setProperty("kaptcha.border", "no");
// 字体颜色
properties.setProperty("kaptcha.textproducer.font.color", "black");
// 字体间距
properties.setProperty("kaptcha.textproducer.char.space", "5");
// 图片宽
properties.setProperty("kaptcha.image.width", "120");
// 图片高
properties.setProperty("kaptcha.image.height", "50");
// 验证码长度
properties.setProperty("kaptcha.textproducer.char.length", "4");
// 噪点生成对象
properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");
// 边框颜色
properties.setProperty("kaptcha.border.color", "105,179,55");
// 字体大小
// properties.setProperty("kaptcha.textproducer.font.size", "30");
// session key
// properties.setProperty("kaptcha.session.key", "code");
// 字体
// properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
Config config = new Config(properties);
kaptcha.setConfig(config);
return kaptcha;
}
}
生成验证码
在这里我们把正确的验证码放到redis中,便于后续的验证
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.me.flashsale.common.Constants;
import com.me.flashsale.domain.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.concurrent.TimeUnit;
/**
* 验证码的生成
*/
@Controller
@Slf4j
@RequestMapping("/kaptcha")
public class KaptchaController {
/**
* 1、验证码工具
*/
@Autowired
private DefaultKaptcha kaptcha;
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 生成验证码
* @param httpServletResponse
* @param user
* @param goodsId
* @throws Exception
*/
@RequestMapping("/jpg")
public void getKaptcha(HttpServletResponse httpServletResponse, User user, long goodsId)
throws Exception {
byte[] captchaChallengeAsJpeg;
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
try {
// 生产验证码字符串并保存到redis中
String rightCode = kaptcha.createText();
log.info("rightCode:{}", rightCode);
redisTemplate.opsForValue().set(Constants.Cache.KAPTCHA_REDIS_PREFIX+user.getId()+"_goods"+goodsId, rightCode,
Constants.Cache.KAPTCHA_EXPIRE_TIME, TimeUnit.SECONDS);
// 使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
BufferedImage challenge = kaptcha.createImage(rightCode);
ImageIO.write(challenge, "jpg", jpegOutputStream);
} catch (IllegalArgumentException e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 定义response输出类型为image/jpeg类型,使用response输出流输出图片的byte数组
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
httpServletResponse.setHeader("Cache-Control", "no-store");
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setDateHeader("Expires", 0);
httpServletResponse.setContentType("image/jpeg");
ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
}
}
前端使用
使用的方式很简单,直接img标签的src属性调用controller的接口即可
验证逻辑
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 校对验证码
* @param user
* @param goodsId
* @param tryCode
* @return
*/
public Boolean imgVerifyCode(User user, long goodsId, String tryCode) {
String rightCode = redisTemplate.opsForValue().get(Constants.Cache.KAPTCHA_REDIS_PREFIX + user.getId()
+"_goods"+ goodsId);
log.info("rightCode={}, tryCode={}", rightCode, tryCode);
return tryCode.equals(rightCode);
}