验证码实现
在项目开发中实现登录的时候需要提供验证码功能, 主要母的是防止机械代码暴力破解密码,
验证码原理是在服务器生成验证码信息并且保存在 session 对象中,
将验证码的副本以流的方式发送一份到浏览器显示页面,
用户再将验证码填写到表单, 提交了服务器端和保存在 session 中的验证码做对比,
如果相同则再继续进行密码和用户名的验证, 如果不相同则提示验证码不正确
(可以通过一些技术实现识别图片中的文字, 为了解决这样的问题, 可以在验证码中添加干扰线)
现在的很多应用是手机短信验证了
Demo: 定义验证码工具类
1 import java.awt.Color; 2 import java.awt.Font; 3 import java.awt.Graphics; 4 import java.awt.image.BufferedImage; 5 import java.io.ByteArrayOutputStream; 6 import java.io.IOException; 7 import java.util.Random; 8 import javax.imageio.ImageIO; 9 import javax.servlet.ServletException; 10 import javax.servlet.ServletOutputStream; 11 import javax.servlet.annotation.WebServlet; 12 import javax.servlet.http.HttpServlet; 13 import javax.servlet.http.HttpServletRequest; 14 import javax.servlet.http.HttpServletResponse; 15 import javax.servlet.http.HttpSession; 16 17 @WebServlet("/imgCode") 18 public class RandomCode extends HttpServlet { 19 private static final long serialVersionUID = 1L; 20 private static int WIDTH = 102;//锟斤拷锟缴碉拷图片锟侥匡拷锟? 21 private static int HEIGHT = 50;// 锟斤拷锟缴碉拷图片锟侥高讹拷 22 public void doGet(HttpServletRequest request, HttpServletResponse response) 23 throws ServletException, IOException { 24 HttpSession session = request.getSession(); 25 response.setContentType("image/jpeg"); 26 ServletOutputStream sos = response.getOutputStream(); 27 response.setHeader("Pragma", "No-cache"); 28 response.setHeader("Cache-Control", "no-cache"); 29 response.setDateHeader("Expires", 0); 30 BufferedImage image = new BufferedImage(WIDTH, HEIGHT, 31 BufferedImage.TYPE_INT_RGB); 32 Graphics g = image.getGraphics(); 33 char[] rands = generateCheckCode(); 34 drawBackground(g); 35 drawRands(g, rands); 36 g.dispose(); 37 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 38 ImageIO.write(image, "JPEG", bos); 39 byte[] buf = bos.toByteArray(); 40 response.setContentLength(buf.length); 41 sos.write(buf); //锟斤拷锟斤拷锟缴碉拷锟斤拷证锟斤拷图片写锟斤拷页锟斤拷 42 bos.close(); 43 sos.close(); 44 //锟斤拷锟斤拷锟缴碉拷锟斤拷证锟诫保锟芥到session 45 session.setAttribute("rand", new String(rands)); 46 } 47 private void drawBackground(Graphics g) { 48 g.setColor(new Color(0xDCDCDC)); 49 g.fillRect(0, 0, WIDTH, HEIGHT); 50 for (int i = 0; i < 120; i++) { 51 int x = (int) (Math.random() * WIDTH); 52 int y = (int) (Math.random() * HEIGHT); 53 int red = (int) (Math.random() * 255); 54 int green = (int) (Math.random() * 255); 55 int blue = (int) (Math.random() * 255); 56 g.setColor(new Color(red, green, blue)); 57 g.drawOval(x, y, 1, 0); 58 } 59 } 60 private void drawRands(Graphics g, char[] rands) { 61 // g.setColor(Color.BLUE); 62 Random random = new Random(); 63 int red = random.nextInt(110); 64 int green = random.nextInt(50); 65 int blue = random.nextInt(50); 66 g.setColor(new Color(red, green, blue)); 67 g.setFont(new Font(null, Font.ITALIC | Font.BOLD, 30)); 68 g.drawString("" + rands[0], 5, 35); 69 g.drawString("" + rands[1], 25, 34); 70 g.drawString("" + rands[2], 45, 36); 71 g.drawString("" + rands[3], 65, 33); 72 } 73 private char[] generateCheckCode() { 74 String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 75 char[] rands = new char[4]; 76 for (int i = 0; i < 4; i++) { 77 int rand = (int) (Math.random() * 36); 78 rands[i] = chars.charAt(rand); 79 } 80 return rands; 81 } 82 public void doPost(HttpServletRequest request, HttpServletResponse response) 83 throws ServletException, IOException { 84 this.doGet(request, response); 85 } 86 }
Demo: 登录中使用验证码
1.定义表单 (刷新验证码,需要添加 jquery.min.js 文件)
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <base href="/MvcPro/"/> 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 8 <title>Insert title here</title> 9 <script type="text/javascript" src="js/jquery.min.js"></script> 10 </head> 11 <body> 12 <span>${msg}</span> 13 <form action="emp/login" method="POST"> 14 <fieldset> 15 <legend>请登录!</legend> 16 用户名: <input type="text" name="username" placehodler="输入用户名"><br><br> 17 密 码 : <input type="password" name="pwd" placehodler="输入密码"><br/><br/> 18 <script src="js/login.js"></script> 19 <img alt="图片不存在" src="imgCode" height="50px"><a href="javascript:void(0)"> 看不清,换一张</a> <br><br> 20 验证码: <input type="text" name="code"> 21 <br><br> 22 <input style="margin-left:60px" type="submit" value="提交"> 23 <input type="reset" value="重置"> 24 </fieldset> 25 </form> 26 <script type="text/javascript"> 27 $(function(){ 28 $("form a").click(function(){ //为 a 标签绑定了一个单机事件 29 $("form img").attr("src","imgCode?ran="+new Date().getTime()); 30 }) 31 }) 32 </script> 33 </body> 34 </html>
2.在服务器使用验证码
1 @SuppressWarnings("serial") 2 @WebServlet(urlPatterns= {"/emp/*","/dept/*"}) 3 public class EmpServlet extends HttpServlet{ 4 @Override 5 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 6 String username = req.getParameter("username"); 7 String pwd = req.getParameter("pwd"); 8 String ranCode = req.getParameter("code"); 9 //先判断验证码是否正确 10 if (ranCode.equalsIgnoreCase((String)req.getSession().getAttribute("rand"))) { 11 if ("smith".equals(username) && "1234".equals(pwd)) { 12 req.getSession().setAttribute("name", username); 13 //跳转到首页 14 resp.sendRedirect("/MvcPro/pages/welcome.jsp"); 15 } else { 16 req.setAttribute("msg", "用户名或密码不正确"); 17 req.getRequestDispatcher("/pages/login.jsp").forward(req, resp); 18 } 19 } else { 20 req.setAttribute("msg", "验证码不正确"); 21 req.getRequestDispatcher("/pages/login.jsp").forward(req, resp); 22 } 23 } 24 @Override 25 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 26 this.doGet(req, resp); 27 } 28 }