验证码的生成与使用,注意验证码session安全

  • Post author:
  • Post category:其他


验证码是为了防止“黑客”利用暴力破解密码而出现的安全技术。比如如果没有验证码,一般登陆页面就会只有登陆名和密码,若“黑客”知道一个用户名后,就可以做一个程序,在那一直猜密码,(也就是暴力破解密码),可如果有的验证码后,这种暴力破解密码的方式就不行了。

通过学习验证码的生成与使用,做一下笔记

1、新建web工程:



2、验证码的本质是在java代码里,通过java的画笔画出来的。首先在jsp页面中添加img标签,来接收画出来的验证码图片,并且,这个图片的来源,也就是src属性,是一个web请求,本次练习使用的是servlet技术。jsp文件中的代码:

<img title="看不清?点击换一个" src="yanZhengCode.servlet"  id="YZcode" />
<p id="next" style="cursor: pointer;">换一张</p>

3、生成验证码的java文件,也就是

yanZhengCode.servlet(要在web.xml中进行配置)中的代码:

package com.wang;
/**
 * 生成验证码
 * @author HeJW
 *
 */
public class YanZheng extends HttpServlet implements Servlet {

	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("image/png");
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		
		
		//如果要全是数字,就把字母去掉
		//String charNumber = "0123456789abcdefghijklmnopqrstuvwxyz";
		String charNumber = "0123456789";
		Random r = new Random();
		String code = "" + charNumber.charAt(r.nextInt(charNumber.length()))
		+ charNumber.charAt(r.nextInt(charNumber.length()))
		+ charNumber.charAt(r.nextInt(charNumber.length()))
		+ charNumber.charAt(r.nextInt(charNumber.length()));
		
		//设置session,方便工程后面使用验证码的值
		request.getSession().setAttribute("YanZheng", code);
		// 生成这么大小的图片
		BufferedImage image = new BufferedImage(100, 45, BufferedImage.TYPE_INT_RGB);
		// 生成画笔
		Graphics g = image.getGraphics();
		// 把生成的图片背景色为淡灰色的
		g.setColor(Color.GRAY.brighter());
		g.fillRect(0, 0, image.getWidth(), image.getHeight());
		//验证码字符的大小
		Font f = new Font("IMPACT", Font.ITALIC, 30);
		g.setFont(f);
		for (int i = 0; i < code.length(); i++) {
			int y = 25;
			g.setColor(Color.black);
			g.drawString("" + code.charAt(i), image.getWidth() / code.length()* i, y);
		}
		ImageIO.write(image, "png", response.getOutputStream());
	}

	protected void doPost(HttpServletRequest requset,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(requset, response);
	}

}


4、此时,在web页面中已经能够显示验证码了,验证码一帮还有一个“换一个”的功能,其实就是让img标签的src属性重新发送一遍,我用的是jquery:

$("#next").click(function() {
$('#YZcode')[0].src="<%=basePath%>yanZhengCode.servlet?timestamp="+new Date().getTime();
});


5、我们再来看看验证码的使用:

package com.wang;

public class YanZhengTest extends HttpServlet implements Servlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response){
		
		HttpSession session = request.getSession();
		
		String yz = (String)request.getParameter("YZtext");
		
		String yzC = (String)session.getAttribute("YanZheng"); 
		//这样每次用完之后都清空一下session,防止验证码session攻击
		session.removeAttribute("YanZheng");
		
		if( yz.equals(yzC)){
			System.out.println("true");
		} else {
			System.out.println("false");
		}
		
		try {
			response.sendRedirect("index.jsp");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	protected void doPost(HttpServletRequest requset,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(requset, response);
	}

	
	
}


6、全部源码:


web.xml中的配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>YanZhengCord</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>

	<servlet>
		<servlet-name>Servlet1</servlet-name>
		<servlet-class>com.wang.YanZheng</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>Servlet1</servlet-name>
		<url-pattern>/yanZhengCode.servlet</url-pattern>
	</servlet-mapping>

	<servlet>
		<servlet-name>Servlet2</servlet-name>
		<servlet-class>com.wang.YanZhengTest</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>Servlet2</servlet-name>
		<url-pattern>/yanZhengTest.servlet</url-pattern>
	</servlet-mapping>



</web-app>


index.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>验证码小例子</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>

<script type="text/javascript" src="jquery-1.8.2.js"></script>
<script type="text/javascript">
	$(document).ready(function() {
		$("#next").click(function() {
			$('#YZcode')[0].src="<%=basePath%>yanZhengCode.servlet?timestamp="+new Date().getTime();
		});
		
	});
	
</script>

<body>

<img title="看不清?点击换一个" src="yanZhengCode.servlet"  id="YZcode" />
<p id="next" style="cursor: pointer;">换一张</p>

<form action="yanZhengTest.servlet" method="post">
验证码:<input type="text" id="YZtext" name="YZtext"/>
<input type="submit"/>
</form>


</body>
</html>


生成验证码:

package com.wang;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 生成验证码
 * @author HeJW
 *
 */
public class YanZheng extends HttpServlet implements Servlet {

	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("image/png");
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		
		
		//如果要全是数字,就把字母去掉
		//String charNumber = "0123456789abcdefghijklmnopqrstuvwxyz";
		String charNumber = "0123456789";
		Random r = new Random();
		String code = "" + charNumber.charAt(r.nextInt(charNumber.length()))
						+ charNumber.charAt(r.nextInt(charNumber.length()))
						+ charNumber.charAt(r.nextInt(charNumber.length()))
						+ charNumber.charAt(r.nextInt(charNumber.length()));
		
		//设置session,方便工程后面使用验证码的值
		request.getSession().setAttribute("YanZheng", code);
		// 生成这么大小的图片
		BufferedImage image = new BufferedImage(100, 45, BufferedImage.TYPE_INT_RGB);
		// 生成画笔
		Graphics g = image.getGraphics();
		// 把生成的图片背景色为淡灰色的
		g.setColor(Color.GRAY.brighter());
		g.fillRect(0, 0, image.getWidth(), image.getHeight());
		//验证码字符的大小
		Font f = new Font("IMPACT", Font.ITALIC, 30);
		g.setFont(f);
		for (int i = 0; i < code.length(); i++) {
			int y = 25;
			g.setColor(Color.black);
			g.drawString("" + code.charAt(i), image.getWidth() / code.length()* i, y);
		}
		ImageIO.write(image, "png", response.getOutputStream());
	}

	protected void doPost(HttpServletRequest requset,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(requset, response);
	}

}


验证码使用:

package com.wang;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class YanZhengTest extends HttpServlet implements Servlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response){
		
		HttpSession session = request.getSession();
		
		String yz = (String)request.getParameter("YZtext");
		
		String yzC = (String)session.getAttribute("YanZheng"); 
		//这样每次用完之后都清空一下session,防止验证码session攻击
		session.removeAttribute("YanZheng");
		
		if( yz.equals(yzC)){
			System.out.println("true");
		} else {
			System.out.println("false");
		}
		
		try {
			response.sendRedirect("index.jsp");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	protected void doPost(HttpServletRequest requset,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(requset, response);
	}

	
	
}




版权声明:本文为he_jiawang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。