在日常生活中,我们登录网站或者其他平台时,在填写完账号密码之后,还会让我们填写4或6位的数字或者英文字母等,填写正确才能请求登录。这个其实是防止某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,如下图所示:
现在,我们知道登录的时候需要填写验证码的原因,但图形验证码从何得来,是怎么生成的呢,这就需要我们去探索了。当然现在开源代码比较多,我这里推荐的就是一个开源的图形验证码,样式挺好看、类型也很多。
EasyCaptcha源码地址:https://gitee.com/ele-admin/EasyCaptcha
Java图形验证码,支持gif、中文、算术等类型,可用于Java Web、JavaSE等项目。
在IDEA中新建一个SpringBoot项目,版本为2.0以上的即可,在pom.xml中添加easycaptcha依赖,代码如下:
<!-- 图形验证码 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>
在项目中新建一个VerificationCode类,用来设置验证码图片的属性,包括宽度、高度、位数等操作。,代码如下:
/**
* 生成验证码图片的宽度
*/
private int width = 100;
/**
* 生成验证码图片的高度
*/
private int height = 30;
/**
* 生成验证码的位数
*/
private int digit = 4;
/**
* 生成的验证码code
*/
private String captchaCode;
接着在该类中新建一个生成验证码图形的方法。
/**
* 生成验证码
*
* @return
*/
public SpecCaptcha createVerificationCode() throws IOException, FontFormatException {
// 三个参数分别为宽、高、位数
SpecCaptcha specCaptcha = new SpecCaptcha(width, height, digit);
// 设置字体
specCaptcha.setFont(Captcha.FONT_9);
// 设置类型,纯数字、纯字母、字母数字混合
specCaptcha.setCharType(Captcha.TYPE_ONLY_NUMBER);
// 验证码
this.captchaCode = specCaptcha.text().toLowerCase();
return specCaptcha;
}
我这里选择的是纯数字的类型,字体为FONT_9,在项目中可根据自己的需要进行修改。
接下来,写一个生成验证码的接口,将我们后端生成的数字以图片的格式返给前端展示。新建一个controller包,然后创建一个LoginController类。在该类中创建一个生成验证码的方法,并把图片以base64的格式输出,代码如下:
@GetMapping("/captcha")
public void getVerifyCode(HttpServletResponse response) throws IOException, FontFormatException {
try {
// 设置请求头为输出图片类型
VerificationCode code = new VerificationCode();
SpecCaptcha specCaptcha = code.createVerificationCode();
// 创建字节数组输出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 将验证码图片输出到字节数组输出流中
specCaptcha.out(baos);
// 将字节数组转换为 Base64 编码
byte[] imageBytes = baos.toByteArray();
InputStream inStream = new ByteArrayInputStream(imageBytes);
OutputStream outputStream = null;
outputStream = new BufferedOutputStream(response.getOutputStream());
//创建存放文件内容的数组
byte[] buff = new byte[1024];
//所读取的内容使用n来接收
int n;
//当没有读取完时,继续读取,循环
while ((n = inStream.read(buff)) != -1) {
//将字节数组的数据全部写入到输出流中
outputStream.write(buff, 0, n);
}
//强制将缓存区的数据进行输出
outputStream.flush();
//关流
outputStream.close();
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
接下来,启动项目,然后在浏览器中,访问:http://localhost:8080/captcha地址,则就可以获取到图形验证码的图片。