Kaptcha实现的验证码功能

验证码分析

1.    选型

经过在github和google code上搜索之后,初步选择了两种方案:jQuery.buttonCaptchakaptcha

jQuery.buttonCaptcha需要引用jquery一系列文件,对于没有采用jquery的系统中会造成加载资源过多,影响页面速度。

Kaptcha使用java来生成验证码,可配置(自定义)验证码的类型(中文,字母,数字)、字体类型、字体颜色、图片的宽度和高度、图片边框、干扰线、样式等。可配置,因此使用方便;而且支持扩展。

基于以上判断,我建议使用kaptcha。

2.    Kaptcha的使用

Kaptcha使用很方便,通过servlet来访问。在web项目中,可以这样配置。

kaptcha

com.google.code.kaptcha.servlet.KaptchaServlet

kaptcha.border

no

kaptcha.border.color

105,179,90

kaptcha.textproducer.font.color

red

kaptcha.image.width

200

kaptcha.image.height

50

kaptcha.textproducer.font.size

40

kaptcha.textproducer.char.length

4

kaptcha.textproducer.font.names

仿宋_GB2312

kaptcha

/kaptcha.jpg

在页面中,可以这样使用

Kaptcha在生成验证码图片的同时,会将验证码的内容放入session中,key是com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY。这样,我们就可以在服务端验证用户输入的验证码是否正确了。

以上配置是针对普通web项目的,如果采用了spring mvc框架的项目,要采取另外一种配置方式,这种配置方式session中无法获得验证码的值。

在spring mvc中,要为它单独配置一个controller

首先新建一个文件 applicationContext-kaptcha.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-2.5.xsd">

no

105,179,90

blue

130

30

40

4

宋体,楷体,微软雅黑

之后,新建一个controller

package cn.com.gei.htic.platform.portal.controller;

 

importjava.awt.image.BufferedImage;

 

import javax.imageio.ImageIO;

importjavax.servlet.ServletOutputStream;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

 

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.stereotype.Controller;

importorg.springframework.web.bind.annotation.RequestMapping;

importorg.springframework.web.servlet.ModelAndView;

 

importcom.google.code.kaptcha.Constants;

importcom.google.code.kaptcha.Producer;

 

@Controller

@RequestMapping("/kaptcha")

@Controller

public classKaptchaController {

privateProducer captchaProducer = null;

 

@Autowired

publicvoid setCaptchaProducer(Producer captchaProducer) {

this.captchaProducer= captchaProducer;

}

 

@RequestMapping("/captcha-image")

publicModelAndView handleRequest(HttpServletRequest request,

            HttpServletResponse response) throws Exception {

 

        response.setDateHeader("Expires", 0);

        // Set standard HTTP/1.1 no-cache headers.

        response.setHeader("Cache-Control",

                "no-store, no-cache, must-revalidate");

        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).

        response.addHeader("Cache-Control","post-check=0, pre-check=0");

        // Set standard HTTP/1.0 no-cache header.

        response.setHeader("Pragma", "no-cache");

        // return a jpeg

        response.setContentType("image/jpeg");

        // create the text for the image

        String capText = captchaProducer.createText();

        // store the text in the session

        request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY,

                capText);

        // create the image with the text

        BufferedImage bi = captchaProducer.createImage(capText);

        ServletOutputStream out = response.getOutputStream();

        // write the data out

        ImageIO.write(bi, "jpg", out);

        try {

            out.flush();

        } finally {

            out.close();

        }

        return null;

    }

}

然后新建一个aptcha-servlet.xml,放在WEB-INF下

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:p="http://www.springframework.org/schema/p"

    xmlns:context="http://www.springframework.org/schema/context"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   

        base-package=" cn.com.gei.htic.platform.portal.controller"/>

   

        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

   

        class="org.springframework.web.servlet.view.UrlBasedViewResolver">

       

            value="org.springframework.web.servlet.view.JstlView"/>

       

       

   

最后在web.xml中配置

        aptcha

        org.springframework.web.servlet.DispatcherServlet

        1

        aptcha

        /aptcha/*

 

在页面中,可以通过如下方式来使用:

参考:http://ttaale.iteye.com/blog/808719

3.    与Spring Security结合

这里 的与Spring Security结合,是指登录页面的验证码验证问题。

首先在Spring Security的配置文件中增加如下内容:

意思是不对验证码进行权限验证

之后要自定义一个filter

中增加

PRE_AUTH_FILTER的意思是在Spring Security验证之前进行的验证,具体可以参考这里

http://static.springsource.org/spring-security/site/docs/3.0.x/reference/preauth.html

之后增加aptchaFilter的定义

        class="cn.com.gei.kmp4.kjjexternal.security.filter.AptchaFilter">

   

   

   

        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">

   

引用的authenticationManager是别名

其中loginSuccessHandler可以采用kmp4默认的。

AptchaFilter的定义如下:

public class AptchaFilterextends UsernamePasswordAuthenticationFilter {

 

    @Override

    public Authentication attemptAuthentication(HttpServletRequestrequest,

            HttpServletResponse response) throws AuthenticationException{

        checkValidateCode(request);

        return super.attemptAuthentication(request, response);

    }

 

    protected void checkValidateCode(HttpServletRequest request) {

        String sessionValidateCode =obtainSessionValidateCode(request);

        String validateCodeParameter =obtainValidateCodeParameter(request);

        if (sessionValidateCode != null

                &&!sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {

            throw new AuthenticationServiceException(messages

                    .getMessage("validateCode.notEquals"));

        }

    }

 

    private String obtainSessionValidateCode(HttpServletRequestrequest) {

        HttpSession session = request.getSession(true);

        String code = (String) session

                .getAttribute(Constants.KAPTCHA_SESSION_KEY);

        return code;

    }

 

    private String obtainValidateCodeParameter(HttpServletRequestrequest) {

      //yanzheng 是页面中验证码输入框的name

        return request.getParameter("yanzheng");

    }

}

此filter继承自 UsernamePasswordAuthenticationFilter,重写了attemptAuthentication方法,在此方法中,我们可以增加对验证码的验证逻辑

如果验证失败,则抛出AuthenticationServiceException异常,异常的提示信息可以结合本地message策略,在org/springframework/security/messages_zh_CN.properties中增加一条,这里采用的是

validateCode.notEquals    验证码不正确

通过配置simpleUrlAuthenticationFailureHandler,我们就可以在这个filter验证失败后,将页面重定向到登录页面,从而实现验证码的验证了。

4.    参数含义

 

Constant

Description

Default

常数

描述

默认值

kaptcha.border

有无边框,选项是yes或者no

Yes

kaptcha.border.color

边框颜色。可选值为red,green,blue 或者white,black,blue

Black

kaptcha.border.thickness

边框厚度,可选值为大于0的整数

1

kaptcha.image.width

图片宽度(像素)

200

kaptcha.image.height

图片高度(像素)

50

kaptcha.producer.impl

图片生产者

com.google.code.kaptcha.impl.DefaultKaptcha  (可自定义,实现Producer接口即可)

kaptcha.textproducer.impl

字体产生者

com.google.code.kaptcha.text.impl.DefaultTextCreator(可自定义,实现TextProducer接口即可)

kaptcha.textproducer.char.string

图片内容从这些字符中产生

abcde2345678gfynmnpwx

kaptcha.textproducer.char.length

图片内容的长度

5

kaptcha.textproducer.font.names

图片字体名,用逗号隔开。

Arial, Courier

kaptcha.textproducer.font.size

图片字体大小

40px

kaptcha.textproducer.font.color

图片字体颜色,可选值为red,green,black等

black

kaptcha.textproducer.char.space

字符之间空格数

2

kaptcha.noise.impl

噪度生产者

com.google.code.kaptcha.impl.DefaultNoise

(可自定义,实现NoiseProducer接口即可)

kaptcha.noise.color

噪度颜色,可选值为red,green,black等

Black

kaptcha.obscurificator.impl

模糊度实现者

com.google.code.kaptcha.impl.WaterRipple (可自定义,实现GimpyEngine接口即可)

kaptcha.background.impl

背景实现者

com.google.code.kaptcha.impl.DefaultBackground(可自定义,实现BackgroundProducer接口即可)

kaptcha.background.clear.from

背景颜色开始值,可选值是red,green,blue等

Light grey

kaptcha.background.clear.to

背景颜色结束值,可选值是red,green,blue

White

kaptcha.word.impl

字体渲染实现者

com.google.code.kaptcha.text.impl.DefaultWordRenderer(可自定义,实现WordRenderer接口即可)

kaptcha.session.key

验证码内容生成后会放入HttpSession中,这是内容在session中的key值

KAPTCHA_SESSION_KEY (程序有bug,建议不要配,程序中可通过session.getAttribute(Constants.KAPTCHA_SESSION_KEY)来取)

kaptcha.session.date

验证码生成的日期会放入HttpSession中,这是日期在session中的key值

KAPTCHA_SESSION_DATE

 

5.    刷新验证码

// 点击刷新验证码

   $(function(){

      $('#id_captchaImage').click(function(){

          $(this).hide().attr('src','/kaptcha/captcha-image?'+ Math.floor(Math.random()*100)).fadeIn();

      });

   });

你可能感兴趣的:(web)