此处使用kaptcha依赖实现图形验证码校验功能
引入依赖
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
Kaptcha 相关配置
配置kaptcha实例
@Bean public Producer captcha() { // 配置图形验证码的基本参数 Properties properties = new Properties(); // 图片宽度 properties.setProperty("kaptcha.image.width", "150"); // 图片长度 properties.setProperty("kaptcha.image.height", "50"); // 字符集 properties.setProperty("kaptcha.textproducer.char.string", "0123456789"); // 字符长度 properties.setProperty("kaptcha.textproducer.char.length", "4"); Config config = new Config(properties); // 使用默认的图形验证码实现,当然也可以自定义实现 DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); defaultKaptcha.setConfig(config); return defaultKaptcha; }
配置kaptcha路由
@Controller public class CaptchaController { @Autowired private Producer captchaProducer; @GetMapping("/captcha.jpg") public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException { // 设置内容类型 response.setContentType("image/jpeg"); // 创建验证码文本 String capText = captchaProducer.createText(); // 将验证码文本设置到session request.getSession().setAttribute("captcha", capText); // 创建验证码图片 BufferedImage bi = captchaProducer.createImage(capText); // 获取响应输出流 ServletOutputStream out = response.getOutputStream(); // 将图片验证码数据写到响应输出流 ImageIO.write(bi, "jpg", out); // 推送并关闭响应输出流 try { out.flush(); } finally { out.close(); } } }
在security config方法中对所有kaptcha请求放行
.antMatchers("/app/api/**", "/captcha.jpg").permitAll()
配置过滤器
security的过滤器链表示所有的过滤器功能,(Security全局配置中的HttpSecurity即表示配置了一个过滤器链)。诸如CSRF、formLogin等等。每一项httpsecurity的配置即表示一个过滤器链中的过滤器配置。
这里涉及到的是,在Security框架提供的过滤器之外,自定义的过滤器。
注意:第七行需改成项目对应的login路由。
public class VerificationCodeFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
System.out.println("into filter");
// 非登录请求不校验验证码
if (!"/customlogin".equals(httpServletRequest.getRequestURI())) {
filterChain.doFilter(httpServletRequest, httpServletResponse);
} else {
verificationCode(httpServletRequest);
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
public void verificationCode (HttpServletRequest httpServletRequest) throws VerificationCodeException {
String requestCode = httpServletRequest.getParameter("captcha");
HttpSession session = httpServletRequest.getSession();
String savedCode = (String) session.getAttribute("captcha");
System.out.println("---> " + savedCode);
if (!StringUtils.isEmpty(savedCode)) {
// 随手清除验证码,不管是失败还是成功,所以客户端应在登录失败时刷新验证码
session.removeAttribute("captcha");
}
// 校验不通过抛出异常
if (StringUtils.isEmpty(requestCode) || StringUtils.isEmpty(savedCode) || !requestCode.equals(savedCode)) {
throw new VerificationCodeException();
}
}
}
抛出的异常:
public class VerificationCodeException extends AuthenticationException {
public VerificationCodeException () {
super("图形验证码校验失败");
}
}
配置页面
表单中添加以下内容即可
<div>
<!-- 新增图形验证码的输入框 -->
<input type="text" name="captcha" placeholder="captcha" />
<!-- 图片指向图形验证码API -->
<img src="/captcha.jpg" alt="captcha" height="50px" width="150px" style="margin-left: 20px;">
</div>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。