Servlet經典小功能-利用Session實現一次性驗證碼
阿新 • • 發佈:2018-12-05
為了保證使用者資訊的安全,都會在網站登入的介面裡新增一次性驗證碼,從而限制有人會用軟體指令碼暴力猜測密碼。一次性驗證碼的功能可以使用Session來實現。
為了避免使用者輸入的驗證碼太長,本節要實現的驗證碼是4個隨機字元。同時,將驗證碼以圖片的形式展示給使用者,從而增加工具程式識別驗證碼的難度,登入介面驗證碼效果如圖所示:
Login.html程式碼如下:
<form name="reg" action="/chapter06/LoginServlet"method="post"> 使用者名稱:<input name="username" type="text" /><br/> 密碼 :<input name="password" type="password" /><br/> 驗證碼:<input type="text" name="check_code"> <img src="/chapter06/CheckServlet"><br> <input type="submit" value="提交" id="bt"/> </form>
CheckServlet類用於產生驗證碼圖片,程式碼如下:
package cn.itcast.chapter06.session.example02; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @WebServlet("/CheckServlet") public class CheckServlet extends HttpServlet { private static int WIDTH = 60; //驗證碼圖片寬度 private static int HEIGHT = 20; //驗證碼圖片高度 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); response.setContentType("image/jpeg"); ServletOutputStream sos = response.getOutputStream(); //設定瀏覽器不要快取此圖片 response.setHeader("Pragam", "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); 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 = "0123456789abcdefghjklmnopqrstuvwxyz"; 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() * 225); int green = (int)(Math.random() * 225); int blue = (int)(Math.random() * 225); g.setColor(new Color(red,green,blue)); g.drawOval(x, y, 1, 0); } } }