一、第三方验证码API
1、引入 kaptcha-datasource-spring-boot-starter。
引入kaptcha-spring-boot-starter: 基于 SpringBoot Google Kaptcha 验证码 快速启动器的验证码生成包
<dependency><groupId>com.baomidou</groupId><artifactId>kaptcha-spring-boot-starter</artifactId><version>${version}</version>
</dependency>
2、在Controller使用Kaptcha
@Autowiredprivate Kaptcha kaptcha;
@GetMapping("/generator")public void generatorCode(HttpServletRequest request, HttpServletResponse response) {System.out.println("-- 进入生成校验码 ---");kaptcha.render();}
3、提供的异常处理
import com.baomidou.kaptcha.exception.KaptchaException;
import com.baomidou.kaptcha.exception.KaptchaIncorrectException;
import com.baomidou.kaptcha.exception.KaptchaNotFoundException;
import com.baomidou.kaptcha.exception.KaptchaTimeoutException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = KaptchaException.class)public String kaptchaExceptionHandler(KaptchaException kaptchaException) {if (kaptchaException instanceof KaptchaIncorrectException) {return "验证码不正确";} else if (kaptchaException instanceof KaptchaNotFoundException) {return "验证码未找到";} else if (kaptchaException instanceof KaptchaTimeoutException) {return "验证码过期";} else {return "验证码渲染失败";}}
}
4、引入自定义配置
在application.yml中配置如下:
kaptcha:height: 50width: 200content:length: 4source: abcdefghjkmnopqrstuvwxyz23456789space: 2font:color: blackname: Arialsize: 40background-color:from: lightGrayto: whiteborder:enabled: truecolor: blackthickness: 1
5、验证结果
二、自定义验证码
查看源码,得知这个将验证码缓存在session中,存在一定的网络安全问题。
public String render() {this.response.setDateHeader("Expires", 0L);this.response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");this.response.addHeader("Cache-Control", "post-check=0, pre-check=0");this.response.setHeader("Pragma", "no-cache");this.response.setContentType("image/jpeg");String sessionCode = this.kaptcha.createText();
try {ServletOutputStream out = this.response.getOutputStream();Throwable var3 = null;
String var4;try {this.request.getSession().setAttribute("KAPTCHA_SESSION_KEY", sessionCode);this.request.getSession().setAttribute("KAPTCHA_SESSION_DATE", System.currentTimeMillis());ImageIO.write(this.kaptcha.createImage(sessionCode), "jpg", out);var4 = sessionCode;} catch (Throwable var14) {var3 = var14;throw var14;} finally {if (out != null) {if (var3 != null) {try {out.close();} catch (Throwable var13) {var3.addSuppressed(var13);}} else {out.close();}}
}
return var4;} catch (IOException var16) {throw new KaptchaRenderException(var16);}}
我们可以将此处存储方式改为redis存储。
@Overridepublic String render() {response.setDateHeader(HttpHeaders.EXPIRES, 0L);response.setHeader(HttpHeaders.CACHE_CONTROL, "no-store, no-cache, must-revalidate");response.addHeader(HttpHeaders.CACHE_CONTROL, "post-check=0, pre-check=0");response.setHeader(HttpHeaders.PRAGMA, "no-cache");response.setContentType("image/jpeg");String sessionCode = kaptcha.createText();try (ServletOutputStream out = response.getOutputStream()) {// 放到redisstringRedisTemplate.opsForValue().set("eric",sessionCode);ImageIO.write(kaptcha.createImage(sessionCode), "jpg", out);return sessionCode;} catch (IOException e) {throw new KaptchaRenderException(e);}}