安全机制-验证码实例

  个人理解:验证码主要用于防止暴力破解(如一些刷票神器,抢票助手等)非人为操作一种安全机制。该机制将信息(以字符为主)验证用图片的形式输出到客户端,这样有效防止验证信息元数据的泄露,也有效杜绝了部分非人为操作对系统进行访问。

  如下是验证码实现步骤:

1.编写服务端servlet源码

package com.bao.tools.authenticode;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
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;

/**
 * @title 验证码
 * @author Administrator
 * @date 2015-7-18
 */
@SuppressWarnings("serial")
public class Authenticode extends HttpServlet {
    //建立输出验证码字符的集合
    private static String codeChars = "0123456789abcdefghigklmnopqrstuvwxyzACEFMNOPTWXYHG";
    
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置浏览器缓存
        response.setHeader("ragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        
        int charsLength = codeChars.length();//获得验证码字符的总字符长度
        //设置验证码图像宽和高
        int width = 90;
        int height = 30;
        
        //获得图像缓冲对象(宽,高,颜色值类型)
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //获得画出图像的Graphics对象
        Graphics graphics = image.getGraphics();
        graphics.setColor(getRandomColor(130, 230));//设置填充颜色
        graphics.fillRect(0, 0, width, height);//设置图像背景
        //设置字体
        graphics.setFont(new Font("楷体", Font.BOLD, height));
        graphics.setColor(getRandomColor(5, 239));
        
        //产生随机验证码字符
        Random random = new Random();//产生随机字符对象
        StringBuilder builder = new StringBuilder();//本次验证码字符串
        //验证码随机字体集合
        String[] fontNames ={"宋体","楷体","仿宋","Consolas","Arial"};
        //产生3-5个随机字符
        for(int i=0;i<3+random.nextInt(3);i++){
            //随机设置字符字体
            graphics.setFont(new Font(fontNames[random.nextInt(3)], Font.ITALIC, height));
            graphics.setColor(getRandomColor(50, 200));
            //获得当前字符
            char codeChar = codeChars.charAt(random.nextInt(charsLength));
            builder.append(codeChar);//添加到字符串
            //画出字符(字符串,X轴,Y轴)
            graphics.drawString(String.valueOf(codeChar), 16*i+random.nextInt(6), height-random.nextInt(6));
        }
        //获得HttpSession对象
        HttpSession session = request.getSession();
        session.setMaxInactiveInterval(60);//设置有效时间为60秒
        session.setAttribute("authenticode", builder.toString());
        graphics.dispose();//释放画图对象
        OutputStream os = response.getOutputStream();//获得输出流对象
        ImageIO.write(image, "jpeg", os);//输出图像
    }
    /*
     * 返回一个随机颜色
     */
    private static Color getRandomColor(int min,int max){
        Random random = new Random();//随即函数对象
        //设置RGB三基色色值范围
        if(min>255)min=255;
        if(max>255)max=255;
        
        //设置RGB三基色值
        int red = min+random.nextInt(max-min);
        int green = min+random.nextInt(max-min);
        int blue = min+random.nextInt(max-min);        
        
        return new Color(red,green,blue);
    }
}

2.编写用于显示验证码的JSP页面(只做了验证码显示)

<%@ 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>用户登录</title>
</head>
<script type="text/javascript">
    //刷新验证码
    function refresh(){
        var img = document.getElementById("authenti");
        img.src="<%=request.getContextPath()%>/authenti?" + Math.random();
    }
</script>
<body>

    <!-- 如下是验证码模块 -->
    验证码:
    <input type="text" name="authenicode" maxlength="5"
        style=" 50px;" />
    <a href="#"><img id="authenti" title="刷新验证码" alt="验证码"
        src="<%=request.getContextPath()%>/authenti" onclick="refresh();"></a>
</body>
</html>

3.配置web.xml(访问servlet类,将代码贴入web-app标签内部)

  <!-- 验证码配置 -->
  <servlet>
      <servlet-name>authenticode</servlet-name>
      <servlet-class>com.bao.tools.authenticode.Authenticode</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>authenticode</servlet-name>
      <url-pattern>/authenti</url-pattern>
  </servlet-mapping>
  <!-- 验证码结束 -->

4.发布应用到服务器(本案例为tomcat服务器)

5.启动服务器并访问页面

  至此,验证码功能完成了!

原文地址:https://www.cnblogs.com/rick168/p/4656434.html