kaptcha是一款开源生成验证码的工具。不仅能让我们更方便的生成验证码,还能根据喜好提供对验证码的一系列变形。
引用依赖:
<!-- https://mvnrepository.com/artifact/com.github.penggle/kaptcha -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
前端使用kptcha:
首先做好配置工作,kptcha依赖,如果是ssm还要配置文件上传解析器等等这些就先不说,都能找到相关资料,这里讲主要的工作原理和必要步骤
1:在web.xml配置好kptcha(分配路由):
servlet>
<servlet-name>Kaptcha</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
<!--是否有边框-->
<init-param>
<param-name>kaptcha.border</param-name>
<param-value>no</param-value>
</init-param>
<!--字体颜色-->
<init-param>
<param-name>kaptcha.textproducer.font.color</param-name>
<param-value>red</param-value>
</init-param>
<!--图片宽度-->
<init-param>
<param-name>kaptcha.image.width</param-name>
<param-value>135</param-value>
</init-param>
<!--使用哪些字符生成验证码-->
<init-param>
<param-name>kaptcha.textproducer.char.string</param-name>
<param-value>ACDEFHKPRSTWX345679</param-value>
</init-param>
<!--图片高度-->
<init-param>
<param-name>kaptcha.image.height</param-name>
<param-value>50</param-value>
</init-param>
<!--字体大小-->
<init-param>
<param-name>kaptcha.textproducer.font.size</param-name>
<param-value>43</param-value>
</init-param>
<!--干扰线的颜色-->
<init-param>
<param-name>kaptcha.noise.color</param-name>
<param-value>black</param-value>
</init-param>
<!--字符个数-->
<init-param>
<param-name>kaptcha.textproducer.char.length</param-name>
<param-value>4</param-value>
</init-param>
<!--字体-->
<init-param>
<param-name>kaptcha.textproducer.font.names</param-name>
<param-value>Arial</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Kaptcha</servlet-name>
<url-pattern>/Kaptcha</url-pattern>
</servlet-mapping>
2:在前端中使用kptcha:
<img id="captcha_img" alt="点击更换" title="点击更换"
onclick="changeVerifyCode(this)" src="../Kaptcha" />
这里src=”../Kaptcha“,是因为我的html在WEB-INF目录下,所以得返回到application Context下,前端显示如下:
changeVerifyCode(this)是功能是:点击图片更换验证码:
function changeVerifyCode(img) {
img.src = "../Kaptcha?" + Math.floor(Math.random() * 100);
}
这里的"?" 按我原理理解应该是有参数才行的,看了老师的讲解原理是:这样做是可以清理缓存,比如在引入一个js文件,如果js文件名不改变,需要清理缓存才会生效,所有加上"?+随机数"后,就可以达到清理缓存的效果,验证码不能留缓存,茅舍顿开。
这样子就达到我们打开就有验证码,点击就更换验证码的效果。
后端验证:
package com.huang.util;
import com.google.code.kaptcha.Constants;
import javax.servlet.http.HttpServletRequest;
/**
* @ClassName CodeUtil
* @Description 验证码校验工具类
* @Author hjj
* @Date 2022/3/3
*/
public class CodeUtil {
public static boolean checkVerifyCode(HttpServletRequest request){
//看、kaptcha生成的验证码
String verifyCodeExpected= (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
//用户输入的验证码
String verifyCodeActula=request.getParameter("verifyCodeActual");
if (verifyCodeActula==null||!verifyCodeExpected.equals((verifyCodeActula))){
return false;
}
return true;
}
}
这里verifyCodeExpected是获取kptcha生成的验证码(也就是那张图片),源代码待会分析,为啥是这样获取。
verifyCodeActula则是前端传回的参数。
个人简单分析了一下kptcha的原理:
首先我们看看为什么要去web.xml注册的kaptcha:
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
这是web.xml的绑定,接下来我们看KaptchaServlet类。
可以看到这里KaptchaServlet类是实现了servlet,这就是为什么我们需要在web.xml中注册绑定了,因为servlet如果不注册web是访问不到的,所以我们为KaptchaServlet分配了路由。
KaptchaServlet doget()方法:
这里我们可以请求后会往session中写入验证码,而key则需要是这段代码
this.sessionKeyValue = config.getSessionKey();
我们去看跟踪过去看看
可以看到返回的是KAPTCHA_SESSION_KEY
让我们看看kaptcha中Constans类
所以我们session存在一个(KAPTCHA_SESSION_KEY,capText)的键值对,这里就很好解释了我们在想要对用户输入的验证码进行比对的时候为什么要写成
request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
这样就能从Session中获取到生成的验证码了,而且每次请求后都会在Session更新新的验证码。
最后一些Kptcha参数介绍:
Constant | 描述 | 默认值 |
kaptcha.border | 图片边框,合法值:yes , no | yes |
kaptcha.border.color | 边框颜色,合法值: r,g,b (and optional alpha) 或者 white,black,blue. | black |
kaptcha.border.thickness | 边框厚度,合法值:>0 | 1 |
kaptcha.image.width | 图片宽 | 200 |
kaptcha.image.height | 图片高 | 50 |
kaptcha.producer.impl | 图片实现类 | com.google.code.kaptcha.impl.DefaultKaptcha |
kaptcha.textproducer.impl | 文本实现类 | com.google.code.kaptcha.text.impl.DefaultTextCreator |
kaptcha.textproducer.char.string | 文本集合,验证码值从此集合中获取 | abcde2345678gfynmnpwx |
kaptcha.textproducer.char.length | 验证码长度 | 5 |
kaptcha.textproducer.font.names | 字体 | Arial, Courier |
kaptcha.textproducer.font.size | 字体大小 | 40px |
kaptcha.textproducer.font.color | 字体颜色,合法值: r,g,b 或者 white,black,blue. | black |
kaptcha.textproducer.char.space | 文字间隔 | 2 |
kaptcha.noise.impl | 干扰实现类 | com.google.code.kaptcha.impl.DefaultNoise |
kaptcha.noise.color | 干扰颜色,合法值: r,g,b 或者 white,black,blue. | black |
kaptcha.obscurificator.impl | 图片样式: 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy | com.google.code.kaptcha.impl.WaterRipple |
kaptcha.background.impl | 背景实现类 | com.google.code.kaptcha.impl.DefaultBackground |
kaptcha.background.clear.from | 背景颜色渐变,开始颜色 | light grey |
kaptcha.background.clear.to | 背景颜色渐变,结束颜色 | white |
kaptcha.word.impl | 文字渲染器 | com.google.code.kaptcha.text.impl.DefaultWordRenderer |
kaptcha.session.key | session key | KAPTCHA_SESSION_KEY |
kaptcha.session.date | session date | KAPTCHA_SESSION_DATE |