欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-04 14:13:09
...

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

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

1、新建web工程:

验证码的生成与使用,注意验证码session安全
            
    
    博客分类: ToolCord 验证码session安全 
 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);
	}

	
	
}

 

 

 

 

  • 验证码的生成与使用,注意验证码session安全
            
    
    博客分类: ToolCord 验证码session安全 
  • 大小: 13.7 KB