说明:验证码,是登录流程中必不可少的一环,一般企业级的系统,使用都是专门制作验证码、审核校验的第三方SDK(如极验)。本文介绍,使用谷歌提供的Kaptcha技术,制作一个简单的验证码。
本文参考(http://t.csdn.cn/55Ip2),基本是根据这篇文章自己手动实现了一遍。
后端代码
创建一个SpringBoot项目,依赖如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>kaptcha_essay</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!--Springboot项目-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.12</version>
<relativePath/>
</parent>
<dependencies>
<!--web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--kaptcha依赖-->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
</project>
创建一个Kaptcha配置类,用于设置验证码的尺寸、样式等,注意不要漏掉@Component注解
如下:
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.util.Properties;
@Component
public class KaptchConfig {
@Bean
public DefaultKaptcha getDefaultKaptcha() {
// 创建验证码工具
com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha();
// 验证码配置
Properties properties = new Properties();
// 图片边框
properties.setProperty("kaptcha.border", "no");
// 边框颜色
properties.setProperty("kaptcha.border.color", "black");
//边框厚度
properties.setProperty("kaptcha.border.thickness", "1");
// 图片宽
properties.setProperty("kaptcha.image.width", "120");
// 图片高
properties.setProperty("kaptcha.image.height", "60");
//图片实现类
properties.setProperty("kaptcha.producer.impl", "com.google.code.kaptcha.impl.DefaultKaptcha");
//文本实现类
properties.setProperty("kaptcha.textproducer.impl", "com.google.code.kaptcha.text.impl.DefaultTextCreator");
//文本集合,验证码值从此集合中获取
properties.setProperty("kaptcha.textproducer.char.string", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
//验证码长度
properties.setProperty("kaptcha.textproducer.char.length", "4");
//字体
properties.setProperty("kaptcha.textproducer.font.names", "宋体");
//字体颜色
properties.setProperty("kaptcha.textproducer.font.color", "black");
//文字间隔
properties.setProperty("kaptcha.textproducer.char.space", "4");
//干扰实现类
properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.DefaultNoise");
//干扰颜色
properties.setProperty("kaptcha.noise.color", "blue");
//干扰图片样式
properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple");
//背景实现类
properties.setProperty("kaptcha.background.impl", "com.google.code.kaptcha.impl.DefaultBackground");
//背景颜色渐变,结束颜色
properties.setProperty("kaptcha.background.clear.to", "white");
//文字渲染器
properties.setProperty("kaptcha.word.impl", "com.google.code.kaptcha.text.impl.DefaultWordRenderer");
// 创建验证码配置实例
Config config = new Config(properties);
// 验证码工具
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
创建一个controller层类,用于生成验证码并返回
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Map;
@RestController
@CrossOrigin
@RequestMapping("/code")
public class KaptchController {
@Resource
DefaultKaptcha defaultKaptcha;
/**
* 生成验证码
*/
@GetMapping
public Map code() throws IOException {
// 生成文字验证码
String text = defaultKaptcha.createText();
System.out.println("文字验证码为" + text);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// 生成图片验证码
BufferedImage image = defaultKaptcha.createImage(text);
ImageIO.write(image, "jpg", out);
// 对字节组Base64编码
return Map.of("data", Base64.getEncoder().encodeToString(out.toByteArray()));
}
}
@CrossOrigin注解,用于解决跨域问题,待会儿前端会发送异步请求,获取验证码;
前端代码
创建一个前端页面,使用axios向后端发送获取验证码的请求;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>获取验证码</title>
<script src="js/axios-0.18.0.js"></script>
</head>
<body>
<input type="button" value="获取验证码" onclick="get()">
<img id="pic" />
</body>
<script>
function get() {
// 异步交互ajax
axios.get("http://localhost:8080/code") // 发请求给服务器
.then(resp => {
// 接收响应回来的数据
console.log(resp.data);
document.getElementById("pic").src = 'data:image/jpeg;base64,' + resp.data.data;
})
}
</script>
</html>
启动&测试
启动代码,打开前端页面,点击获取验证码,查看结果,如下:
控制台输出验证码,这个验证码在实际开发中可存入Redis中;
可以前端查看返回的内容;
这段地址加上data:image/jpeg;base64,
就是验证码的图片地址;