使用google开源的验证码实现类库kaptcha,经过maven坐标引入前端
<dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> <exclusions> <exclusion> <artifactId>javax.servlet-api</artifactId> <groupId>javax.servlet</groupId> </exclusion> </exclusions> </dependency>
kaptcha.border=no kaptcha.border.color=105,179,90 kaptcha.image.width=100 kaptcha.image.height=45 kaptcha.session.key=code kaptcha.textproducer.font.color=blue kaptcha.textproducer.font.size=35 kaptcha.textproducer.char.length=4 kaptcha.textproducer.font.names=宋体,楷体,微软雅黑
下面的代码加载了配置文件中的kaptcha配置(参考Spring Boot的配置加载),若是是独立的properties文件,需加上PropertySource注解说明。
另外,咱们经过加载完成的配置,初始化captchaProducer的Spring Bean,用于生成验证码。java
@Component @PropertySource(value = {"classpath:kaptcha.properties"}) public class CaptchaConfig { @Value("${kaptcha.border}") private String border; @Value("${kaptcha.border.color}") private String borderColor; @Value("${kaptcha.textproducer.font.color}") private String fontColor; @Value("${kaptcha.image.width}") private String imageWidth; @Value("${kaptcha.image.height}") private String imageHeight; @Value("${kaptcha.session.key}") private String sessionKey; @Value("${kaptcha.textproducer.char.length}") private String charLength; @Value("${kaptcha.textproducer.font.names}") private String fontNames; @Value("${kaptcha.textproducer.font.size}") private String fontSize; @Bean(name = "captchaProducer") public DefaultKaptcha getKaptchaBean() { DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); Properties properties = new Properties(); properties.setProperty("kaptcha.border", border); properties.setProperty("kaptcha.border.color", borderColor); properties.setProperty("kaptcha.textproducer.font.color", fontColor); properties.setProperty("kaptcha.image.width", imageWidth); properties.setProperty("kaptcha.image.height", imageHeight); properties.setProperty("kaptcha.session.key", sessionKey); properties.setProperty("kaptcha.textproducer.char.length", charLength); properties.setProperty("kaptcha.textproducer.font.names", fontNames); properties.setProperty("kaptcha.textproducer.font.size",fontSize); Config config = new Config(properties); defaultKaptcha.setConfig(config); return defaultKaptcha; } }
至此,Kaptcha开源验证码软件的配置咱们就完成了,若是发现IDEA环境下配置文件读取中文乱码,修改以下配置。
git
生成验证码的Controller。同时须要开放路径"/kaptcha"的访问权限,配置成不需登陆也无需任何权限便可访问的路径。如何进行配置,笔者以前的文章已经讲过了。github
@RestController public class CaptchaController { @Resource DefaultKaptcha captchaProducer; /** * 获取验证码 */ @RequestMapping(value = "/kaptcha", method = RequestMethod.GET) public void kaptcha(HttpSession session, HttpServletResponse response) throws Exception { response.setDateHeader("Expires", 0); response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); response.addHeader("Cache-Control", "post-check=0, pre-check=0"); response.setHeader("Pragma", "no-cache"); response.setContentType("image/jpeg"); String capText = captchaProducer.createText(); CaptchaImageVO captchaImageVO = new CaptchaImageVO(capText,2 * 60); //将验证码存到session session.setAttribute(Constants.KAPTCHA_SESSION_KEY, captchaImageVO); //将图片返回给前端 try(ServletOutputStream out = response.getOutputStream();) { BufferedImage bi = captchaProducer.createImage(capText); ImageIO.write(bi, "jpg", out); out.flush(); }//使用try-with-resources不用手动关闭流 } }
咱们要把CaptchaImageVO保存到session里面。因此该类中不要加图片,只保存验证码文字和失效时间,用于后续验证便可。把验证码图片保存起来既没有用处,又浪费内存。spring
@Data public class CaptchaImageVO { //验证码文字 private String code; //验证码失效时间 private LocalDateTime expireTime; public CaptchaImageVO(String code, int expireAfterSeconds){ this.code = code; this.expireTime = LocalDateTime.now().plusSeconds(expireAfterSeconds); } //验证码是否失效 public boolean isExpried() { return LocalDateTime.now().isAfter(expireTime); } }
把以下代码加入到登陆页面合适的位置,注意图片img标签放到登陆表单中。api
<img src="/kaptcha" id="kaptcha" width="110px" height="40px"/> <script> window.onload=function(){ var kaptchaImg = document.getElementById("kaptcha"); kaptchaImg.onclick = function(){ kaptchaImg.src = "/kaptcha?" + Math.floor(Math.random() * 100) } } </script>
以上是在Spring Security实现登陆验证码验证的逻辑。若是你是使用的shiro或者其余的自定义的登陆验证明现,那就更简单了。就在你的登陆验证的controller里面取出session比对验证码便可,不须要自定义过滤器。安全