一、图形验证码是什么?
图形验证码是一些没有规则的图文的组合,参考下图
二、图形验证码有什么用?
防止恶意攻击者采用恶意工具批量注册账号或是大量频繁调用某些请求,给服务器造成压力,占用大量的系统资源。
三、图形验证码怎么实现?
(一)后台代码
// 创建一张图片
int width = 120;
int height = 25;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 创建一支画笔
Graphics2D graphics = image.createGraphics();
// 给画笔添加颜色
graphics.setColor(Color.white);
// 填充矩形
graphics.fillRect(0, 0, width, height);
String str = this.getString();
HttpSession session = arg0.getSession();
// 将字符串存入session
session.setAttribute("yzm", str);
Random random = new Random();
// 根据验证码长度随机画干扰线(颜色随机,位置随机,长度随机)
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
Font font = new Font("微软雅黑", Font.BOLD, 22);
graphics.setFont(font);
Color color = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
graphics.setColor(color);
graphics.drawString(String.valueOf(c), 20 + i * 15, 20);
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
int x2 = random.nextInt(width);
int y2 = random.nextInt(height);
graphics.drawLine(x1, y1, x2, y2);
}
// 把图像刷到BufferedImage对象中
graphics.dispose();
// 将图像写入 File,并指定图片格式
ImageIO.write(image, "jpg", arg1.getOutputStream());
/**
* 生成一个长度为4的字符串(随机包含大写字母,小写字母,数字)
*
* @return
*/
public String getString() {
Random random = new Random();
String str = "";
for (int i = 0; i < 4; i++) {
int num = random.nextInt(3);
switch (num) {
case 0:// 数字
int number = random.nextInt(10);
str += number;
break;
case 1:// 小写字母
int lower = random.nextInt(26) + 97;
str += (char) lower;
break;
case 2:// 大写字母
int upper = random.nextInt(26) + 65;
str += (char) upper;
break;
default:
System.out.println("error");
break;
}
}
return str;
}
PS:可将以上代码封装成一个实体类,然后提供一个公开的访问方法,这样更符合Java的封装思想
(二)前台代码(参考)
<form action="#" method="post">
<p>
用户名:<input type="text" name="s_Name" />
</p>
<p>
密码:<input type="password" name="s_Password" />
</p>
<!-- img标签中src属性值"Code"是生成验证码图形Servlet的名称 -->
<p>
验证码<input type="text" id="yzm" name="yzm" /><img src="Code"
onclick="this.src='Code?random='+Math.random()" border="1" id="code" />
<a href="javascript:void(0)">看不清?换一张</a>
</p>
<p>
<input type="submit" value="登录" /> <input type="reset"
value="重置" />
</p>
</form>
<script type="text/javascript">
$(function() {//模拟点击事件,达到切换图形验证码的效果
$("p a").click(function() {
$("#code").trigger("click");
})
})
</script>
PS:验证码在请求Servlet时应加一个随机参数(如:Math.random()或new Date().getTime()),避免浏览器判断图片请求的地址和参数相同,在不刷新页面的情况下,浏览器默认会缓存第一次请求的内容,导致图片并没有更新
四、注意事项
一个实际有效的验证码还必须满足:
(1)生成过程安全:图片验证码必须在服务器端进行产生与校验;
(2)使用过程安全:单次有效,且以用户的验证请求为准;
(3)验证码自身安全:不易被识别工具识别,能有效防止暴力破解。