结合开源软件kaptcha讲解登录验证码功能的实现

网友投稿 700 2022-05-30

一、验证码生成之配置使用kaptcha

使用google开源的验证码实现类库kaptcha,通过maven坐标引入

com.github.penggle kaptcha 2.3.2 javax.servlet-api javax.servlet

假设我们的配置文件是application.yml,新建一个单独的文件叫做kaptcha.properties。因为kaptcha的配置不符合yaml的规范格式,所以只能采用properties。需配合注解PropertySourc使用。

假设我们的配置文件是application.properties,将下面这段代码加入进去即可,不用单独建立文件。

下面的验证码配置,从英文单词的角度很容易理解,当我们需要调整验证码的边框、颜色、大小、字体等属性的时候,可以修改这些配置。

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,用于生成验证码。

@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环境下配置文件读取中文乱码,修改如下配置。

二、验证码生成之session保存

生成验证码的Controller。同时需要开放路径"/kaptcha"的访问权限,配置成不需登录也无需任何权限即可访问的路径。如何进行配置,笔者之前的文章已经讲过了。

通过captchaProducer.createText()生成验证码文字,并和失效时间一起保存到CaptchaImageVO中。

将CaptchaImageVO验证码信息类对象,保存到session中。(这个类的代码后文有介绍)

通过captchaProducer.createImage(capText)生成验证码图片,并通过ServletOutputStream返回给前端

@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里面。所以该类中不要加图片,只保存验证码文字和失效时间,用于后续验证即可。把验证码图片保存起来既没有用处,又浪费内存。

@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标签放到登录表单中。

实现的效果是,页面初始化即加载验证码。以后每一次点击,都会更新验证码。

注意:一定设置width和height,否则图片无法显示。

四、验证码之安全校验

编写我们的自定义图片验证码过滤器VerificationCodeFilter,过滤器中拦截登录请求

VerificationCodeFilter过滤器中从seesion获取验证码文字与用户输入比对,比对通过执行其他过滤器链

比对不通过,自定义一个异常,交给AuthenticationFailureHandler处理

最后将VerificationCodeFilter放在UsernamePasswordAuthenticationFilter表单过滤器之前执行。

以上是在Spring Security实现登录验证码验证的逻辑。如果你是使用的shiro或者其他的自定义的登录验证实现,那就更简单了。就在你的登录验证的controller里面取出session比对验证码即可,不需要自定义过滤器。

期待您的关注

向您推荐博主的系列文档:《手摸手教您学习SpringBoot系列-16章97节》

本文转载注明出处(必须带连接,不能只转文字):字母哥博客。

Spring

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:从课堂走向实践还有多远?
下一篇:TX2刷机与相关软件安装
相关文章