javaweb開發之利用session實現一次性驗證碼

1、一次性驗證碼的做用

防止暴力破解。

2、實現 

1.建立jsp頁面,在頁面中添加一個img標籤,指向一個生成圖片的servlet,設置img寬度和高度  javascript

2.建立生成圖形驗證碼的Servlet  html

該Servlet根據生成的隨機碼產生一個圖形流並返回,能夠將該圖形作一些混淆操做,同時將該隨機碼保存到當前用戶session中。  java

3.驗證碼比對  瀏覽器

將用戶提交上來的驗證碼和保存到當前用戶session中的隨機碼進行比對。  緩存

4.刷新驗證碼。 服務器

使用javascript刷新驗證碼。  session

3、示例代碼

login.jsp app

<%@ 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>Insert title here</title>
<script type="text/javascript">
	function change() {
		var contextPath = document.getElementById("contextPath").value;
		document.getElementById("randomCode").src = contextPath+"/randomCode?"+Math.random();
	}
</script>
</head>
<body>
<input type="hidden" id="contextPath" value="<%=request.getContextPath() %>">
<form method="post" action="<%=request.getContextPath() %>/login">
<table>
	<tr>
		<td>姓名:</td>
		<td><input type="text" name="username" /></td>
	</tr>
	<tr>
		<td>密碼:</td>
		<td><input type="password" name="password" /></td>
	</tr>
	<tr>
		<td>驗證碼:</td>
		<td><input type="text" name="randomCode" /></td>
	</tr>
	<tr>
		<td></td>
		<td colspan="2"><img alt="" src="<%=request.getContextPath() %>/randomCode" width="100"
			height="35" id="randomCode" title="看不清楚,點擊換一張" onclick="change()" /></td>
	</tr>
	<tr>
		<td colspan="2"><input type="submit" value="登錄" /></td>
	</tr>
</table>
</form>
</body>
</html>
RandomCodeServlet.java
package cn.heimar.randomCode;

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.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class RandomCodeServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		int randomNumber = 5;
		// 圖片寬度
		int width = 100;
		// 圖片高度
		int height = 35;
		// 建立隨機碼
		char[] ranlist = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
				.toCharArray();
		StringBuilder sb = new StringBuilder();
		Random randomer = new Random();
		for (int i = 0; i < randomNumber; i++) {
			sb.append(ranlist[randomer.nextInt(ranlist.length)]);
		}
		// 保存到session中
		HttpSession session = req.getSession();
		session.setAttribute("RANDOM_IN_SESSION", sb.toString());

		// 畫畫
		// 建立一個圖片對象
		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_BGR);
		// 獲得圖片對象對應的繪畫緩存,繪畫都在Graphics對象上
		Graphics g = image.getGraphics();

		// 繪製背景
		g.setColor(Color.WHITE);
		// 填充矩形
		g.fillRect(0, 0, width, height);
		// 繪製邊框
		g.setColor(Color.BLACK);
		g.drawRect(0, 0, width - 1, height - 1);
		// 繪製文字
		g.setColor(Color.GRAY);
		g.setFont(new Font("宋體", Font.ITALIC, 24));
		g.drawString(sb.toString(), 13, height - 9);

		//繪製干擾點
		for (int i = 0; i < 300; i++) {
			g.fillRect(randomer.nextInt(width - 1),
					randomer.nextInt(height - 1), 1, 1);
		}
		// 關閉繪畫資源
		g.dispose();

		//清除圖片緩存:IE7  firefox驗證碼沒有反應問題
		//設定網頁的到期時間,一旦過時則必須到服務器上從新調用
		resp.setDateHeader("Expires",-1);
		//Cache-Control指定請求和響應遵循的緩存機制   no-cache指示請求或響應消息不能緩存
		resp.setHeader("Cache-Control","no-cache");
		//是用於設定禁止瀏覽器從本地機的緩存中調閱頁面內容,設定後一旦離開網頁就沒法從Cache中再調出
		resp.setHeader("Pragma","no-cache");
		
		// 輸出
		ImageIO.write(image, "JPG", resp.getOutputStream());
	}

}

LoginServlet.java dom

package cn.heimar.randomCode;

import java.io.IOException;

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 LoginServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		HttpSession session = req.getSession();
		String randomForm = req.getParameter("randomCode");
		String username = req.getParameter("username");
		String randomInSession = (String) session
				.getAttribute("RANDOM_IN_SESSION");
		if (randomForm.equals(randomInSession)) {
			req.getRequestDispatcher("/WEB-INF/success.jsp").forward(req, resp);
			session.removeAttribute("RANDOM_IN_SESSION");
		} else {
			resp.sendRedirect(req.getContextPath()+"/login.jsp");
		}
	}

}

4、個別瀏覽器驗證碼不能刷新的問題 

1.問題說明 

在IE6下面圖片刷新正常,但IE7和Firefox瀏覽器刷新不成功。 

2.緣由分析 

若是新的圖片跟舊的圖片地址不同,圖片刷新會正常。可是驗證碼功能訪問圖片的地址是同樣的。所以瀏覽器自動讀取的是緩存中的內容。 

3.解決方法 

3.1利用隨機數 

將js中路徑後加上Math.random(); 
function change() {
    var contextPath = document.getElementById("contextPath").value;
    document.getElementById("randomCode").src = contextPath+"/randomCode?"+Math.random();
}

3.2利用時間戳 

function change() {
    var contextPath = document.getElementById("contextPath").value;
    document.getElementById("randomCode").src = contextPath+"/randomCode?"+Date.parse(new Date());
}
相關文章
相關標籤/搜索