zoukankan      html  css  js  c++  java
  • 图片校验码的生成

    进入首页,会显示一个彩色图形验证码,用户根据图片上的文字输入文本框。

    如果输入错误,会提示输入与图片文字不同,并更新验证码。

    输入正确会显示成功信息。

    彩色验证码用来防止恶意程序自动发送垃圾消息,或者是恶意程序循环尝试登录密码。人眼可以根据图片了解验证码的内容,但如果是程序就需要扫描图片分析图片中的内容,为了加大程序分析破解的难度,我们还为图片准备了干扰用的背景颜色,并随便修改文字的颜色。这些都是为了加大程序破解的难度。

    现在所有的注意力都集中到如何动态生成校验用的图片,看一下index.jsp中的代码。

    <img src="captcha.jpg" />

    大家可能感到奇怪了,这里img标签对应的是一个静态jpg图片,为什么每次刷新显示的图片内容都不同呢?仔细检查12-01目录下我们也看不到captcha.jpg这个图片,这个图片到底是从哪里得到的呢?在html里包含的图片,css样式表,js脚本,视频等等外部资源,都需要浏览器再次向服务器发起请求。现在我们进行的请求是一个名叫captcha.jpg的图片,而服务器上并没有这个图片,从web.xml里的配置可以看到如下配置。

    <servlet>
        <servlet-name>CaptchaServlet</servlet-name>
        <servlet-class>anni.CaptchaServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CaptchaServlet</servlet-name>
        <url-pattern>/captcha.jpg</url-pattern>
    </servlet-mapping>
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    
        //设置页面不缓存
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
    
        // 在内存中创建图象
        int width = 60, height = 20;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    
        // 获取图形上下文
        Graphics g = image.getGraphics();
    
        //生成随机类
        Random random = new Random();
    
        // 设定背景色
        g.setColor(getRandColor(200, 250));
        g.fillRect(0, 0, width, height);
    
        //设定字体
        g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
    
        //画边框
        //g.setColor(new Color());
        //g.drawRect(0, 0, width - 1, height - 1);
    
    
        // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
        g.setColor(getRandColor(160, 200));
        for (int i = 0; i < 155; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            g.drawLine(x,y,x+xl,y+yl);
        }
    
        // 取随机产生的认证码(4位数字)
        String sRand = "";
        for (int i = 0;i < 4; i++) {
            String rand = String.valueOf(random.nextInt(10));
            sRand += rand;
            // 将认证码显示到图象中
            // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            g.drawString(rand, 13 * i + 6, 16);
        }
    
        // 将认证码存入SESSION
        request.getSession().setAttribute("captcha", sRand);
    
        // 图象生效
        g.dispose();
    
        // 输出图象到页面
        ImageIO.write(image, "JPEG", response.getOutputStream());
    }

    代码最先设置response(响应)中的头部配置,告诉浏览器不要缓存对/captcha.jpg的请求结果,这样才能保证每次刷新页面都看到最新生成的图片,要是设置了缓存很可能每次看到的都是最先请求看到的图片。

    中间一大段代码实现动态生成图片的功能,我们先随机获得几个数字,然后写到BufferedImage中,最后就可以把图片数据写到response,因为图片是二进制数据,所以我们使用了response.getOutputStream()而不是response.getWriter()。

    为了达到验证的功能,每次生成图片之后要记得讲随机得到的数字保存到session中,session中的变量可以跨越多个请求周期存在,等用户输入验证码提交后就能与session中的数据做比较了,这些是在CheckServlet中实现的。、

    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    
        HttpSession session = request.getSession();
    
        String requestCaptcha = request.getParameter("captcha");
        String sessionCaptcha = (String) session.getAttribute("captcha");
    
        if (sessionCaptcha != null && sessionCaptcha.equals(requestCaptcha)) {
            session.removeAttribute("captcha");
            request.getRequestDispatcher("/success.jsp").forward(request, response);
        } else {
            request.setAttribute("message", "验证码输入错误");
            request.getRequestDispatcher("/index.jsp").forward(request, response);
        }
    }
        
  • 相关阅读:
    搜索引擎的排序技术
    搜索引擎的检索模型-查询与文档的相关度计算
    搜索引擎网页排序算法
    IntelliJ IDEA全局内容搜索和替换
    Java8 利用Lambda处理List集合循环给另外一个List赋值过滤处理
    Java时间串获取(格式:yyyyMMddHHmmss)
    Java int转string 长度不足左补0
    float:浮点型double:双精度实型decimal:数字型单精度浮点数(Single)双精度浮点数(double)
    java 集合框架 Java集合&List的实现
    CSRF 攻击的应对之道
  • 原文地址:https://www.cnblogs.com/wenjieyatou/p/6112380.html
Copyright © 2011-2022 走看看