首先添加maven坐标
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
之后添加配置文件
@Component
public class KaptchaConfig {
@Bean
public DefaultKaptcha getDDefaultKaptcha() {
DefaultKaptcha dk = new DefaultKaptcha();
Properties properties = new Properties();
// 图片边框
properties.setProperty("kaptcha.border", "yes");
// 边框颜色
properties.setProperty("kaptcha.border.color", "105,179,90");
// 字体颜色
properties.setProperty("kaptcha.textproducer.font.color", "red");
// 图片宽
properties.setProperty("kaptcha.image.width", "110");
// 图片高
properties.setProperty("kaptcha.image.height", "40");
// 字体大小
properties.setProperty("kaptcha.textproducer.font.size", "30");
// session key
properties.setProperty("kaptcha.session.key", "code");
// 验证码长度
properties.setProperty("kaptcha.textproducer.char.length", "4");
// 字体
properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
Config config = new Config(properties);
dk.setConfig(config);
return dk;
}
之后添加Controller,设置图片的头部相应信息
@RestController
public class CaptchaController {
@Resource
public DefaultKaptcha defaultKaptcha;
@RequestMapping(value = "/image",method = RequestMethod.GET)
public void kaptcha(HttpSession session, HttpServletResponse httpServletResponse)throws IOException{
httpServletResponse.setDateHeader("Exoires",0);
httpServletResponse.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
httpServletResponse.setHeader("Cache-Control", "post-check=0,pre-check=0");
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setHeader("Content-Type", "image/jpeg");
httpServletResponse.setContentType("image/jpeg");
//向浏览器输出验证码
String capText =defaultKaptcha.createText();
//当前的文档存到session 2分钟后过期
session.setAttribute("captcha_key",new CaptchaImageModel(capText,2*60));
ServletOutputStream outputStream = httpServletResponse.getOutputStream();
BufferedImage bufferedImage = defaultKaptcha.createImage(capText);
//image输出到浏览器
ImageIO.write(bufferedImage,"jpg",outputStream);
//刷新缓冲
outputStream.flush();
}
}
返回页面就可以看到验证码加载出来了,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f3Ixi9Nk-1659691054115)(/upload/2022/08/image.png)]
接下来可以对登陆这块的验证
如果使用的是 spring security 那么需要在SecurityConfig配置类添加
@Resource
private CaptchaCodeFilter captchaCodeFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.addFilterBefore(captchaCodeFilter, UsernamePasswordAuthenticationFilter.class);
}
CaptchaCodeFilter 为请求过滤器 其中代码如下主要判断请求验证码这块的内容
@Component
public class CaptchaCodeFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
//判断只有在登陆请求的时候才有验证码的过滤操作
//判断是否是login登陆的,且是post请求
if (StringUtils.equals("/login",httpServletRequest.getRequestURI()) && StringUtils.equalsIgnoreCase(httpServletRequest.getMethod(),"post")){
try {
this.validate(new ServletWebRequest(httpServletRequest));
} catch (AuthenticationException e) {
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.getWriter().write(new ObjectMapper().writeValueAsString(RespBean.error("验证码错误" + e.getMessage())));
return;
}
}
//如果不是直接过滤
filterChain.doFilter(httpServletRequest,httpServletResponse);
}
private void validate(ServletWebRequest servletWebRequest) throws ServletRequestBindingException {
//获取session值
HttpSession session = servletWebRequest.getRequest().getSession();
//获取请求中的验证码值 直接在上面传Request直接获取也可以,下面的这个是第二种方法获取的
String captchaCode = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), "captchaCode");
//判断验证码是否为空
if (StringUtil.isEmpty(captchaCode)){
//跑出session验证器的异常
throw new SessionAuthenticationException("验证码不能为空");
}
//通过session获取验证码 转到 CaptchaImageModel类
CaptchaImageModel captchaImageModel = (CaptchaImageModel) session.getAttribute("captcha_key");
//判断类是否为空
if(Objects.isNull(captchaImageModel)){
throw new SessionAuthenticationException("验证码不存在!");
}
//判断验证码是否过期
if(captchaImageModel.isExpired()){
throw new SessionAuthenticationException("验证码已过期!");
}
//判断验证码是否一样
if (StringUtils.equals(captchaImageModel.getCode(),captchaCode)){
throw new SessionAuthenticationException("验证码不匹配!");
}
}
}