利用Session实现一次性验证码(多学一招)

一、说明

在实际开发中,为了保护用户信息的安全,都会在网站登录界面上添加一次性验证码,从而限制人们使用软件来暴力猜测密码。在实现用户登录案例中,增加一次性验证码功能。

验证码是4个随机字符,以图片的形式展示给用户。

二、实现步骤

1.修改登录页面login.html

增加验证码输入框和验证码图片

<form name="reg" action="/chapter05/LoginServlet" method="post">     
	用户名: <input name="username" type="text" /><br />                 
	密&nbsp;&nbsp;码:<input name="password" type="password" /><br />   
	验证码:<input type="text" name="check_code">                        
	<img src="/chapter05/CheckServlet"><br>                          
	<input type="submit" value="提交" id="bt" />                       
</form>                                                              

2.创建CheckServlet类

用于产生验证码图片

public class CheckServlet extends HttpServlet
 {
 	private static int WIDTH = 60; //验证码图片宽度
 	private static int HEIGHT = 20; //验证码图片高度
        public void doGet(HttpServletRequest request,HttpServletResponse response) 
 			throws ServletException,IOException{		
 		HttpSession session = request.getSession();
 		response.setContentType("image/jpeg");
 		ServletOutputStream sos = response.getOutputStream();
 		//设置浏览器不要缓存此图片
 		response.setHeader("Pragma","No-cache");
 		response.setHeader("Cache-Control","no-cache");
 		response.setDateHeader("Expires", 0);
 		//创建内存图象并获得其图形上下文
 		BufferedImage image = 
 			new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); 
 		Graphics g = image.getGraphics();
 		//产生随机的认证码
 		char [] rands = generateCheckCode();
 		//产生图像
 		drawBackground(g);
 		drawRands(g,rands);
 		//结束图像的绘制过程,完成图像
 		g.dispose();
 		//将图像输出到客户端
 		ByteArrayOutputStream bos = new ByteArrayOutputStream();
 		ImageIO.write(image, "JPEG", bos);
 		byte [] buf = bos.toByteArray();
 		response.setContentLength(buf.length);
 		//下面的语句也可写成:bos.writeTo(sos);
 		sos.write(buf);
 		bos.close();
 		sos.close();
 		//将当前验证码存入到Session中
 		session.setAttribute("check_code",new String(rands));
 		//直接使用下面的代码将有问题,Session对象必须在提交响应前获得
 	//request.getSession().setAttribute("check_code",new String(rands));
 	}
        //生成一个4字符的验证码
 	private char [] generateCheckCode()
 	{
 		//定义验证码的字符表
 		String chars = "0123456789abcdefghijklmnopqrstuvwxyz";
 		char [] rands = new char[4];
 		for(int i=0; i<4; i++)
 		{
 			int rand = (int)(Math.random() * 36);
 			rands[i] = chars.charAt(rand);
 		}
 		return rands;
 	}
 	private void drawRands(Graphics g , char [] rands)
 	{
 		g.setColor(Color.BLACK);
 		g.setFont(new Font(null,Font.ITALIC|Font.BOLD,18));
 		//在不同的高度上输出验证码的每个字符		
 		g.drawString("" + rands[0],1,17);
 		g.drawString("" + rands[1],16,15);
 		g.drawString("" + rands[2],31,18);
 		g.drawString("" + rands[3],46,16);
 		System.out.println(rands);
 	}
 	private void drawBackground(Graphics g)
 	{
  		//画背景
 		g.setColor(new Color(0xDCDCDC));
 		g.fillRect(0, 0, WIDTH, HEIGHT);
 		//随机产生120个干扰点
 		for(int i=0; i<120; i++)
 		{
 			int x = (int)(Math.random() * WIDTH);
 			int y = (int)(Math.random() * HEIGHT);
 			int red = (int)(Math.random() * 255);
 			int green = (int)(Math.random() * 255);
 			int blue = (int)(Math.random() * 255);
 			g.setColor(new Color(red,green,blue));		
 			g.drawOval(x,y,1,0);
 		}
 	}
 }

3.修改LoginServlet

增加对验证码的判断

/**                                                                                              
 * 添加了验证码                                                                                        
 */                                                                                              
public void doGet(HttpServletRequest request, HttpServletResponse response)                      
		throws ServletException, IOException {                                                   
	response.setContentType("text/html;charset=utf-8");                                          
	String username = request.getParameter("username");                                          
	String password = request.getParameter("password");                                          
	String checkCode = request.getParameter("check_code");                                       
	String savedCode = (String) request.getSession().getAttribute("check_code");                 
	PrintWriter pw = response.getWriter();                                                       
	if (("itcast").equals(username) && ("123").equals(password) && checkCode.equals(savedCode)) {
		User user = new User();                                                                  
		user.setUsername(username);                                                              
		user.setPassword(password);                                                              
		request.getSession().setAttribute("user", user);                                         
		response.sendRedirect("/chapter05/IndexServlet");                                        
	} else if (checkCode.equals(savedCode)) {                                                    
		pw.write("用户名或密码错误,登录失败");                                                               
	} else {                                                                                     
		pw.write("验证码错误");                                                                       
	}                                                                                            
}                                                                                                

三、启动Tomcat,测试验证码

http://localhost:8080/chapter05/login.html

如果用户名和密码正确,但不填验证码:

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值