安全机制-验证码实例
个人理解:验证码主要用于防止暴力破解(如一些刷票神器,抢票助手等)非人为操作一种安全机制。该机制将信息(以字符为主)验证用图片的形式输出到客户端,这样有效防止验证信息元数据的泄露,也有效杜绝了部分非人为操作对系统进行访问。
如下是验证码实现步骤:
1.编写服务端servlet源码
package com.bao.tools.authenticode;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* @title 验证码
* @author Administrator
* @date 2015-7-18
*/
@SuppressWarnings("serial")
public class Authenticode extends HttpServlet {
//建立输出验证码字符的集合
private static String codeChars = "0123456789abcdefghigklmnopqrstuvwxyzACEFMNOPTWXYHG";
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置浏览器缓存
response.setHeader("ragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
int charsLength = codeChars.length();//获得验证码字符的总字符长度
//设置验证码图像宽和高
int width = 90;
int height = 30;
//获得图像缓冲对象(宽,高,颜色值类型)
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//获得画出图像的Graphics对象
Graphics graphics = image.getGraphics();
graphics.setColor(getRandomColor(130, 230));//设置填充颜色
graphics.fillRect(0, 0, width, height);//设置图像背景
//设置字体
graphics.setFont(new Font("楷体", Font.BOLD, height));
graphics.setColor(getRandomColor(5, 239));
//产生随机验证码字符
Random random = new Random();//产生随机字符对象
StringBuilder builder = new StringBuilder();//本次验证码字符串
//验证码随机字体集合
String[] fontNames ={"宋体","楷体","仿宋","Consolas","Arial"};
//产生3-5个随机字符
for(int i=0;i<3+random.nextInt(3);i++){
//随机设置字符字体
graphics.setFont(new Font(fontNames[random.nextInt(3)], Font.ITALIC, height));
graphics.setColor(getRandomColor(50, 200));
//获得当前字符
char codeChar = codeChars.charAt(random.nextInt(charsLength));
builder.append(codeChar);//添加到字符串
//画出字符(字符串,X轴,Y轴)
graphics.drawString(String.valueOf(codeChar), 16*i+random.nextInt(6), height-random.nextInt(6));
}
//获得HttpSession对象
HttpSession session = request.getSession();
session.setMaxInactiveInterval(60);//设置有效时间为60秒
session.setAttribute("authenticode", builder.toString());
graphics.dispose();//释放画图对象
OutputStream os = response.getOutputStream();//获得输出流对象
ImageIO.write(image, "jpeg", os);//输出图像
}
/*
* 返回一个随机颜色
*/
private static Color getRandomColor(int min,int max){
Random random = new Random();//随即函数对象
//设置RGB三基色色值范围
if(min>255)min=255;
if(max>255)max=255;
//设置RGB三基色值
int red = min+random.nextInt(max-min);
int green = min+random.nextInt(max-min);
int blue = min+random.nextInt(max-min);
return new Color(red,green,blue);
}
}
2.编写用于显示验证码的JSP页面(只做了验证码显示)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户登录</title>
</head>
<script type="text/javascript">
//刷新验证码
function refresh(){
var img = document.getElementById("authenti");
img.src="<%=request.getContextPath()%>/authenti?" + Math.random();
}
</script>
<body>
<!-- 如下是验证码模块 -->
验证码:
<input type="text" name="authenicode" maxlength="5"
style="width: 50px;" />
<a href="#"><img id="authenti" title="刷新验证码" alt="验证码"
src="<%=request.getContextPath()%>/authenti" onclick="refresh();"></a>
</body>
</html>
3.配置web.xml(访问servlet类,将代码贴入web-app标签内部)
<!-- 验证码配置 -->
<servlet>
<servlet-name>authenticode</servlet-name>
<servlet-class>com.bao.tools.authenticode.Authenticode</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>authenticode</servlet-name>
<url-pattern>/authenti</url-pattern>
</servlet-mapping>
<!-- 验证码结束 -->
4.发布应用到服务器(本案例为tomcat服务器)
5.启动服务器并访问页面
至此,验证码功能完成了!