图片验证码
# 图片验证码的作用
图片验证码,利用图片生成技术,把文本内容绘制在图片中,用户识别内容与图片内容一致认为验证通过。
该技术的主要作用是为了防止爬虫模拟操作获取系统敏感数据甚至攻击,图片验证码有一定的预防作用,有防就有攻黑客利用图片识别技术 破解验证码,为此图片验证会设置各种干扰参数增加破解难度,近些年出现拼图点图验证,本质都是一样的增加破解验证难度。
# 实现一个图片验证码
本案例采用 单点登录组件 kisso 内置验证码封装
安装依赖
Apache Maven
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>kisso</artifactId>
<version>3.8.1</version>
</dependency>
- Gradle DSL
implementation("com.baomidou:kisso:3.8.1")
- 注入图片验证码
@Bean
public ImageCaptcha imageCaptcha() {
ImageCaptcha imageCaptcha = ImageCaptcha.getInstance();
// 干扰量 1
imageCaptcha.setInterfere(1);
// 验证码内容长度 4 位
imageCaptcha.setLength(4);
// Gif 验证码
// imageCaptcha.setGif(true);
// 验证码存储处理类,默认存在在 session 实现类 CaptchaStoreSession 仅适用单机
// 分布式可以采用 Redis 处理,例如 RedisCaptchaStore 实现 ICaptchaStore 接口
// imageCaptcha.setCaptchaStore(new CaptchaStoreRedis());
return imageCaptcha;
}
配置 imageCaptcha 属性说明
名称 | 说明 |
---|---|
gif | 是否为 GIF 验证码 |
font | 字体 |
rgbArr | RGB 颜色数组 |
interfere | 干扰量 |
interfereColor | 干扰色默认随机 |
color | 验证码颜色默认随机 |
length | 验证码随机字符长度 |
width | 验证码显示宽度 |
height | 验证码显示高度 |
suffix | 图片后缀 |
randomType | 验证码类型:MIX 字母数字混合、NUMBER 数字、CHARACTER 字母、CHINESE 汉字 |
chineseUnicode | 常用汉字 |
captchaStore | 图片验证码票据存储接口 ICaptchaStore |
ignoreCase | 是否忽略验证内容大小写,默认 true |
- 效果图
- Spring Boot 图片验证码生成验证
@RestController
@RequestMapping("/v1/captcha")
public class CaptchaController {
@Resource
protected HttpServletRequest request;
@Resource
protected HttpServletResponse response;
@Resource
private ICaptcha captcha;
// 生成验证,例如:http://localhost:8088/v1/captcha/image?ticket=123456
@GetMapping("/image")
public void image(String ticket) {
try {
// 验证码信息存放在缓存中,key = ticket 、 value = 验证码文本内容
captcha.generate(request, response.getOutputStream(), ticket);
} catch (IOException e) {
e.printStackTrace();
}
}
// 校验图片验证码
@PostMapping("/verification")
public boolean verification(String ticket, String code) {
// ticket 为生成验证码的票据, code 为图片验证码文本内容
return captcha.verification(request, ticket, code);
}
}
- 前端调用
<img src="http://localhost:8088/v1/captcha/image?ticket=123456" width="130px" height="48px" />
注意
- 验证码 ticket 票据可以是前端生成也可以是后端生成( 可以是 UUID、时间戳 ),需要确保每次都不一样。
- 默认验证码实现 session 存储只适用于单机、分布式情况请自行实现 ICaptchaStore 接口注入、存储在分布式介质中例如 Redis 缓存。
# 接入第三方验证码库 EasyCaptcha
该验证码库EasyCaptcha (opens new window)还是挺不错的 Java 图形验证码库,支持gif、中文、算术等类型,有些字体效果也挺漂亮, 喜欢轻量级可以直接采用 kisso 内置的实现,喜欢 EasyCaptcha 库的可以按照如下方法接入。
安装 EasyCaptcha 依賴
Apache Maven
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>
- Gradle DSL
implementation("com.github.whvcse:easy-captcha:1.6.2")
- 实现验证码接口 ICaptcha
public class EasyCaptcha implements ICaptcha {
protected ICaptchaStore captchaStore;
@Override
public void generate(HttpServletRequest request, OutputStream outputStream, String ticket) throws IOException {
SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5);
specCaptcha.out(outputStream);
this.getCaptchaStore(request).put(ticket, specCaptcha.text());
}
@Override
public boolean verification(HttpServletRequest request, String ticket, String captcha) {
String content = this.getCaptchaStore(request).get(ticket);
return null != content ? content.equalsIgnoreCase(captcha) : false;
}
private ICaptchaStore getCaptchaStore(HttpServletRequest request) {
return null == this.captchaStore ? new CaptchaStoreSession(request) : this.captchaStore;
}
}
- 注入图片验证码 EasyCaptcha 实现
/**
* 注入图片验证码
*/
@Bean
public EasyCaptcha easyCaptcha() {
return new EasyCaptcha();
}
- 效果图
具体 使用逻辑参考上文 Spring Boot 图片验证码生成验证
# 接入第三方验证码库 Google Kaptcha
该验证库为 Google 验证码库老牌了,目前中央仓库没有官方坐标,可以去官网http://code.google.com/p/kaptcha/下载jar,或者在pom.xml中导入 ,这里推荐使用第三方上传的坐标:
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
- Gradle DSL
implementation("com.github.penggle:kaptcha:2.3.2")
- 实现验证码接口 ICaptcha
@Component // 这里申明注入,当前也可以上面一样 bean 注入
public class Kaptcha implements ICaptcha {
protected ICaptchaStore captchaStore;
@Override
public void generate(HttpServletRequest request, OutputStream outputStream, String ticket) throws IOException {
// KAPTCHA.createText() 这里可以生成文本,也可以配置自定义 kaptcha.word.impl 文本渲染器
// 这里你自己写一个随机生成文本算法即可
String text = "3x9=?";
ImageIO.write(KAPTCHA.createImage(text), "png", outputStream);
// 存储 ticket 作为 key 验证文本作为 value 这里是图片验证希望得到的实际结果文本
this.getCaptchaStore(request).put(ticket, "27");
}
@Override
public boolean verification(HttpServletRequest request, String ticket, String captcha) {
String content = this.getCaptchaStore(request).get(ticket);
return null != content ? content.equalsIgnoreCase(captcha) : false;
}
private ICaptchaStore getCaptchaStore(HttpServletRequest request) {
return null == this.captchaStore ? new CaptchaStoreSession(request) : this.captchaStore;
}
private static final DefaultKaptcha KAPTCHA;
static {
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "130");
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "48");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
KAPTCHA = defaultKaptcha;
}
}
- 效果图
- 配置属性
Kaptcha 是一个可高度配置的实用验证码生成工具,可自由配置的选项如:
名称 | 默认 | 说明 |
---|---|---|
kaptcha.border | yes | 图片边框,合法值:yes , no |
kaptcha.border.color | black | 边框颜色,合法值: r,g,b (and optional alpha) 或者 white,black,blue |
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 | black | 字体颜色,合法值: r,g,b 或者 white,black,blue |
kaptcha.textproducer.char.space | 2 | 文字间隔 |
kaptcha.noise.impl | com.google.code.kaptcha.impl.DefaultNoise | 干扰实现类 |
kaptcha.noise.color | black | 干扰 颜色,合法值: r,g,b 或者 white,black,blue |
kaptcha.obscurificator.impl | com.google.code.kaptcha.impl.WaterRipple | 图片样式: 水纹 com.google.code.kaptcha.impl.WaterRipple 鱼眼 com.google.code.kaptcha.impl.FishEyeGimpy 阴影 com.google.code.kaptcha.impl.ShadowGimpy |
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 | KAPTCHA_SESSION_KEY | session key |
kaptcha.session.date | KAPTCHA_SESSION_DATE | session date |
# 开源行为式验证码
行为式验证码是一种较为流行的验证码。从字面来理解,就是通过用户的操作行为来完成验证,而无需去读懂扭曲的图片文字。常见的有两种:拖动式与点触式。
基于 Vue3 + Vite + Canvas 开发的滑块验证码 文档地址 (opens new window) 适用于各种表单提交前的验证。
- AJ-Captcha (opens new window) 支持 滑动拼图、点选文字
- SliderCaptcha (opens new window) 滑块验证码
- tianai-captcha (opens new window) 滑块验证码,支持普通图片和 webp图片两种格式
上次更新: 2022/05/05, 16:05:41