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

一、验证码生成之配置使用kaptcha
使用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>
- 假设我们的配置文件是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标签放到登录表单中。
<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>
- 实现的效果是,页面初始化即加载验证码。以后每一次点击,都会更新验证码。
- 注意:一定设置width和height,否则图片无法显示。
四、验证码之安全校验

- 编写我们的自定义图片验证码过滤器VerificationCodeFilter,过滤器中拦截登录请求
- VerificationCodeFilter过滤器中从seesion获取验证码文字与用户输入比对,比对通过执行其他过滤器链
- 比对不通过,自定义一个异常,交给AuthenticationFailureHandler处理
- 最后将VerificationCodeFilter放在UsernamePasswordAuthenticationFilter表单过滤器之前执行。
以上是在Spring Security实现登录验证码验证的逻辑。如果你是使用的shiro或者其他的自定义的登录验证实现,那就更简单了。就在你的登录验证的controller里面取出session比对验证码即可,不需要自定义过滤器。
期待您的关注
- 向您推荐博主的系列文档:《手摸手教您学习SpringBoot系列-16章97节》
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
结合开源软件kaptcha讲解登录验证码功能的实现的更多相关文章
- Springboot +redis+⾕歌开源Kaptcha实现图片验证码功能
Springboot +redis+⾕歌开源Kaptcha实现图片验证码功能 背景 注册-登录-修改密码⼀般需要发送验证码,但是容易被 攻击恶意调⽤ 什么是短信-邮箱轰炸机 手机短信轰炸机是批.循环给 ...
- Vue Springboot (包括后端解决跨域)实现登录验证码功能详细完整版
利用Hutool 基于Vue.ElementUI.Springboot (跨域)实现登录验证码功能 前言 一.Hutool是什么? 二.下面开始步入正题:使用步骤 1.先引入Hutool依赖 2.控制 ...
- springmvc下实现登录验证码功能
总体思路,简单讲,就是后台生成图片同时将图片信息保存在session,前端显示图片,输入验证码信息后提交表单到后台,取出存放在session里的验证码信息,与表单提交的验证码信息核对. 点击验证码图片 ...
- (五)SpringMVC之使用Kaptcha实现验证码功能
一.什么是Kaptcha Kaptcha是Google开发的用于自动生成验证码的插件. 二.怎么导入Kaptcha ① 如果没有用Maven管理工具的话就直接导入包(可以直接下载:pau8) http ...
- SSO单点登录可以自己实现吗?--开源软件诞生10
ERP与SSO的恩怨情仇--第10篇 用日志记录“开源软件”的诞生 赤龙 ERP 开源地址: 点亮星标,感谢支持,与开发者交流 kzca2000 码云:https://gitee.com/redrag ...
- .NET Core实战项目之CMS 第十六章 用户登录及验证码功能实现
前面为了方便我们只是简单实现了基本业务功能的增删改查,但是登录功能还没有实现,而登录又是系统所必须的,得益于 ASP.NET Core的可扩展性因此我们很容易实现我们的登录功能.今天我将带着大家一起来 ...
- spring boot:spring security给用户登录增加自动登录及图形验证码功能(spring boot 2.3.1)
一,图形验证码的用途? 1,什么是图形验证码? 验证码(CAPTCHA)是"Completely Automated Public Turing test to tell Computers ...
- SpringBoot学习:整合shiro(验证码功能和登录次数限制功能)
项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 (一)验证码 首先login.jsp里增加了获取验证码图片的标签: <body s ...
- C#WinForm 实现登录界面验证码功能(区分大小写+不区分大小写)
原文:C#WinForm 实现登录界面验证码功能(区分大小写+不区分大小写) 文章来自:https://blog.csdn.net/IT_xiao_guang_guang/article/detail ...
随机推荐
- JVM(2) Java内存溢出异常
在Java虚拟机运行时数据区中,除了程序计数器之外,虚拟机栈.本地方法栈.方法区和Java堆都有发生OutOfMemoryError(简称OOM)异常的可能. 一.Java堆溢出 Java堆用于存储对 ...
- python实现人工智能Ai抠图功能
这篇文章主要介绍了python实现人工智能Ai抠图功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 自己是个PS小白,没办法只能通过技术来证明自己. 话不多说, ...
- git push 报src refspec xxx does not match any的错误
今天在向一个新的远程分支上推送项目的时候报错: 远程分支branch_new是其他人建的,我在自己本地修改后把自己分支的修改推送到这个远程分支上. 把修改提到本地仓库: git add ./ git ...
- Java12 Collectors.teeing 你需要了解一下
前言 在 Java 12 里面有个非常好用但在官方 JEP 没有公布的功能,因为它只是 Collector 中的一个小改动,它的作用是 merge 两个 collector 的结果,这句话显得很抽象, ...
- MIT线性代数:7.主变量,特解,求解AX=0
- NOIP模拟 9
%liu_runda Orz T1 随 矩阵快速幂结合概率期望 但n3无法承受 利用原根的性质,将乘法转化成加法 就变成循环矩阵n^2了 改题时苦b地卡了关:误把1当成原根的1次方,错误地认为矩阵的阶 ...
- P2115 [USACO14MAR]破坏(二分答案)
给定一串数,问删除中间一段,剩下的平均数最小是多少: 不容易想到这是个二分. $solution:$ 来手玩一点式子: 首先很容易想到一个前缀和$sum_i $表示i到1的前缀和,这样就能很容易地O( ...
- Python - selenium自动化-Chrome(headless)
什么是 Headless Chrome Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序.相比于现代浏览 ...
- CSP-S 95 (sb lsc yy赛)
sb lsc 终于改完题了!(心力交悴.png)
- 深入理解@LoadBalanced注解的实现原理与客户端负载均衡
前提 在阅读这篇博客之前,希望你对SpringCloud套件熟悉和理解,更希望关注下微服务开发平台 概述 在使用springcloud ribbon客户端负载均衡的时候,可以给RestTemplate ...