`
marc0658
  • 浏览: 80354 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

使用Jcaptcha做验证码总结

 
阅读更多

http://my.oschina.net/jawava/blog/8574

 

发现这个社区不错,所以也凑个热闹。

第一篇日志,一定要动手写才有诚意。

这两天要给刚做的外网系统登录页面加验证码,以前没做过。上网搜了一下,资料很多。
验证码校验称作captcha:
Completely Automated Public Test to tell Computers and Humans Apart
专业点儿的翻译是:全自动区分计算机和人类的图灵测试。
CAPTCHA的目的很明确,就是区分计算机和人类的一种程序算法,
这种程序必须能生成并评价人类能很容易通过但计算机却通不过的测试。

网上能查到不少实现方案,简单的写个jsp就行了,技术含量不高。搜了一圈后,
感觉还是用个正规点儿比较合适,然后就锁定了JCaptcha,到其官方网站上看了看:
http://jcaptcha.octo.com/confluence/display/general/Home

JCaptcha提供了
Provide robust and reliable CAPTCHA implementation framework for JAVA
Provide accessible CAPTCHA implementations
Provide multi-type challenge (text, sound, image)

它用上百个类来实现了如此简单的功能,这是为什么呢?官方给的解释是
1、学术界能不断的发明(或发现)一些人类容易处理而机器不能很好处理的问题。
JCaptcha高屋建瓴的给出了一种通用的定义和表达这种问题并用于识别的方案。
也就是识别方案的可扩展性。
2、实现了若干引擎和组件,通过配置这些引擎和组件,可以方便的修改自己程序
captcha构件的算法。这样,在抵御恶意访问时,可以不用改变代码,灵活快速的
改变captcha策略,从而更好的保护系统。

个人觉的说的挺好,第一点对于我们来说倒是次要的,主要第二点比较有意义。
然后就试了试。下面是具体需要做的工作:

一,从官网上下个jcaptcha-1.0-all.jar,加入到项目中,
官方的2.0还没有正式版,所以先用1.0吧。

二,官网上介绍了几种和项目结合的具体方案,最简单的方式很快走通,图片很难看,
而且不具有可配置性,肯定不行。所以选择通过spring来整合的方式,
spring是整合和配置的平台,把jcaptcha的服务和引擎还有组件配置成spring的bean。
示例如下:
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
        "http://www.springframework.org/dtd/spring-beans.dtd">
<beans  default-autowire="byName">

    <bean id="captchaServlet" class="com.jawava.XXXX.XXX.TopImageCaptchaServlet" />

<bean id="captchaService" class="com.octo.captcha.service.multitype.GenericManageableCaptchaService">
<description>验证码服务</description>
<constructor-arg index="0"><ref bean="imageEngine"/></constructor-arg>
<constructor-arg index="1"><value>300</value></constructor-arg><!--超时时间 秒-->
<constructor-arg index="2"><value>20000</value></constructor-arg><!--最大并发数-->
<constructor-arg index="3"><value>20000</value></constructor-arg><!--第四个参数官网示例上没有给出,会报错,后来看了API才知道少了个参数-->
</bean>

<bean id="imageEngine" class="com.octo.captcha.engine.GenericCaptchaEngine">
<description>图片引擎</description>
<constructor-arg index="0">
<list>
<ref bean="CaptchaFactory"/>
</list>
</constructor-arg>
</bean>

<bean id="CaptchaFactory" class="com.octo.captcha.image.gimpy.GimpyFactory" >
<description>验证码工厂</description>
<constructor-arg><ref bean="wordgen"/></constructor-arg>
<constructor-arg><ref bean="wordtoimage"/></constructor-arg>
</bean>

<bean id="wordgen" class= "com.octo.captcha.component.word.wordgenerator.RandomWordGenerator" >
<description>文字产生器,提供了好几种实现,经过比较选用了这种</description>
<constructor-arg index="0"><value>0123456789</value></constructor-arg>
</bean>

<bean id="wordtoimage" class="com.octo.captcha.component.image.wordtoimage.ComposedWordToImage" >
<description>图片生成器</description>
<constructor-arg index="0"><ref bean="fontGenRandom"/></constructor-arg>
<constructor-arg index="1"><ref bean="backGenUni"/></constructor-arg>
<constructor-arg index="2"><ref bean="simpleWhitePaster"/></constructor-arg>
</bean>

<bean id="fontGenRandom" class="com.octo.captcha.component.image.fontgenerator.RandomFontGenerator" >
<description>文字转换图片</description>
<constructor-arg index="0"><value>20</value></constructor-arg><!--字体最小尺寸-->
<constructor-arg index="1"><value>20</value></constructor-arg><!--字体最大尺寸-->
</bean> 

<bean id="backGenUni" class="com.octo.captcha.component.image.backgroundgenerator.GradientBackgroundGenerator" >
<constructor-arg index="0"><value>62</value></constructor-arg><!--背景图片宽度-->
<constructor-arg index="1"><value>22</value></constructor-arg><!--背景图片高度-->
<constructor-arg type="java.awt.Color" index="2">
<ref bean="colorGrey"/>
</constructor-arg> 
<constructor-arg type="java.awt.Color" index="3">
<ref bean="colorGreen"/>
</constructor-arg>

</bean>

<bean id="simpleWhitePaster" class="com.octo.captcha.component.image.textpaster.SimpleTextPaster" >
<constructor-arg type="java.lang.Integer" index="0">
<value>4</value><!--字符最少个数-->
</constructor-arg>
<constructor-arg type="java.lang.Integer" index="1">
<value>4</value><!--字符最多个数-->
</constructor-arg>
<constructor-arg type="java.awt.Color" index="2">
<ref bean="colorFont"/>
</constructor-arg>
</bean>

<bean id="colorGrey" class="java.awt.Color" >
<constructor-arg index="0"><value>200</value></constructor-arg>
<constructor-arg index="1"><value>255</value></constructor-arg>
<constructor-arg index="2"><value>200</value></constructor-arg>
</bean>
<bean id="colorGreen" class="java.awt.Color" >
<constructor-arg index="0"><value>110</value></constructor-arg>
<constructor-arg index="1"><value>120</value></constructor-arg>
<constructor-arg index="2"><value>200</value></constructor-arg>
</bean>
<bean id="colorFont" class="java.awt.Color" >
<constructor-arg index="0"><value>60</value></constructor-arg>
<constructor-arg index="1"><value>60</value></constructor-arg>
<constructor-arg index="2"><value>60</value></constructor-arg>
</bean>
</beans>



这里面具体用哪个component,需要看ApI,我把包里提供的现成的组件基本上试了大半,
最后选择了如上的配置,选择的标准一是美观,二是识别率。识别率太低了,用户体验会下降。

三、配置好后,JCaptcha这边的工作就完成了。下面就是和项目的结合。
1、首先专门写个CaptcahServlet用来获取验证码,由于要在servlet里注入spring的bean,
所以用了代理的方式。代理类网上有,都是固定写法,这里就不贴了。
CaptcahServlet主要部分如下:
@Override
public void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws ServletException, IOException, RuntimeException {

byte[] captchaChallengeAsJpeg = null;
//输出jpg的字节流
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
try {
// get the session id that will identify the generated captcha.
//the same id must be used to validate the response, the session id is a good candidate!
String captchaId = httpServletRequest.getSession().getId();
// call the ImageCaptchaService getChallenge method
BufferedImage challenge =
(BufferedImage) captchaService.getChallengeForID(captchaId,
            httpServletRequest.getLocale());

// a jpeg encoder
    JPEGImageEncoder jpegEncoder =
            JPEGCodec.createJPEGEncoder(jpegOutputStream);
    jpegEncoder.encode(challenge);

} catch (IllegalArgumentException e) {
    httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
    return;
} catch (CaptchaServiceException e) {
    httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    return;
}

captchaChallengeAsJpeg = jpegOutputStream.toByteArray();

// flush it in the response
httpServletResponse.setHeader("Cache-Control", "no-store");
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setDateHeader("Expires", 0);
httpServletResponse.setContentType("image/jpeg");
ServletOutputStream responseOutputStream =
        httpServletResponse.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
    }



然后在web.xml配置:

<servlet>
<servlet-name>CaptchaProxy</servlet-name>
<servlet-class>com.jawava.XXXXX.XXX.TopHttpServletProxy</servlet-class>
<init-param>
<param-name>targetServlet</param-name>
<param-value>captchaServlet</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>CaptchaProxy</servlet-name>
<url-pattern>/topJcaptcha</url-pattern>
</servlet-mapping>



2、目前项目的登录页面是jsp,结合很方便,在原有页面上加上
<img src="/topJcaptcha" /> <input type="text" name="jcaptcha" value="" />
那个img就是校验码。
需要的话,再加上个换图片的功能,很简单。

3、验证环节。我是在原来的验证用户密码的逻辑前,加上了验证码的校验逻辑。
很简单的几句话,代码如下:

Boolean isResponseCorrect =Boolean.FALSE;
        //需要sessionId 来验证校验码
        String sessionId = request.getSession().getId();
//首先校验验证码
        try {
            isResponseCorrect = captchaService.validateResponseForID(sessionId,
             captcha_input);
            if(!isResponseCorrect) {
             throw new RuntimeException("输入的验证码有误,请重新输入");
            }
        } catch (CaptchaServiceException e) {
             //should not happen, may be thrown if the id is not valid
         throw new RuntimeException("校验验证码时出现不明错误",e);
        }



四、如此就可以测试了。通过反复调整参数,达到了比较美观的效果,但是文字始终
不在图片的正中,而是靠上,甚至都把文字掩盖了一半。翻看了半天API,也看不出
个端倪。只好去翻源代码了。问题出在
com.octo.captcha.component.image.textpaster.SimpleTextPaster这个类,它把文字
图片往背景图片放时,把文字的位置放在了背景图片一半的高度上,这就是问题所在。
修改代码重新打了个jar包。替换一下,重启后一切ok。
分享到:
评论

相关推荐

    java jcaptcha 验证码 生成

    总结,Java JCaptcha验证码框架为开发者提供了一种高效且易于集成的验证码解决方案。通过理解和使用JCaptcha,不仅可以增强网站的安全性,还可以为用户提供良好的交互体验。在实际项目中,根据具体需求进行配置和...

    Jcaptcha(java验证码生成框架)使用说明(原创)

    Jcaptcha 是一个 Java 验证码生成框架,提供了详细的说明及例程,通过调查实践后,总结的,希望对大家有帮助。该框架提供了生成验证码图像通用解决办法,提供了非常灵活的生成验证码图像的框架,可以自由的组合生成...

    security+jcaptcha(验证码)+mybatis框架搭建

    ### 安全性 + Jcaptcha (验证码) + MyBatis框架搭建详解 #### 一、项目背景与目标 本文档将详细介绍如何通过整合Spring Security、Jcaptcha和MyBatis框架来构建一个具备安全性验证功能的Web应用。此项目旨在创建一...

    security+jcaptcha(验证码)框架搭建

    根据提供的文件信息,本文将详细介绍如何使用 Spring Security 和 JCaptcha 框架来搭建一个包含验证码功能的安全系统。 ### 一、Spring Security简介 Spring Security 是一个强大的且高度可定制的身份验证和访问...

    JCaptcha验证码生成

    **正文** 验证码是一种用于验证用户...总结,JCaptcha是一个强大且灵活的Java验证码生成库,适用于各种Web应用。理解和掌握JCaptcha的使用,可以帮助开发者构建更安全的系统,防止自动化攻击,保护用户数据的安全。

    JCaptcha 开源的验证码组件

    **JCaptcha开源验证码组件详解** 验证码(CAPTCHA)是一种用于防止自动机器人滥用服务的技术,它通过让用户解决人类容易但机器难以解决的难题来验证用户是否是真实的人。JCaptcha(Just Another CAPTCHA)是一个...

    基于java的验证码生成库 JCaptcha.zip

    总结,JCaptcha作为一个成熟的Java验证码库,为开发者提供了强大而灵活的验证码生成和验证功能,帮助保护应用程序免受自动化攻击。通过了解其核心组件、使用流程以及与其他验证码库的对比,开发者可以更好地利用...

    jcaptcha.rar

    总结,Jcaptcha作为Java平台上的验证码解决方案,为开发者提供了强大而灵活的工具,以确保Web应用的安全性。通过理解其原理和使用方法,开发者可以更好地利用Jcaptcha来构建安全的用户验证机制。

    jcaptcha4struts2-demo-2.0.1.zip_DEMO_JCaptcha4Struts2.jar_jcaptc

    总结来说,"jcaptcha4struts2-demo-2.0.1.zip"提供了一个学习和实践Jcaptcha4Struts2验证码组件的实例。通过这个DEMO,开发者可以了解到如何在Struts2环境中集成和使用验证码,从而提升Web应用的安全性。无论是初学...

    浅析Java验证码生成库JCaptcha

    总结来说,JCaptcha是一个功能丰富的Java验证码生成库,能够帮助开发者快速实现安全的验证码功能。其灵活的配置和多模态支持使得它成为Java平台上的首选验证码解决方案之一。通过学习和使用JCaptcha,开发人员可以为...

    三种方法实现验证码

    总结起来,实现验证码的方法多种多样,本文主要介绍了使用Servlet、JCaptcha和Kaptcha的实现方式。每种方法都有其特点和适用场景,开发者可以根据项目需求选择合适的技术。在实际开发中,验证码的安全性和用户体验都...

    创建验证码工具类(源码)

    总结来说,jcaptcha提供了一种简单的方式来创建和管理验证码。通过`CreateRandomImage`类的源码,我们可以学习到如何在Java项目中集成和使用jcaptcha,以及如何自定义验证码的外观和行为。理解并掌握这些知识点,...

    jcaptcha学习spring整合

    总结,Jcaptcha与Spring的整合是一项增强Web应用安全性的重要任务。通过理解Jcaptcha的核心功能和原理,以及掌握Spring框架的Bean管理,我们可以有效地将二者结合,为用户提供安全、可靠的验证码服务。同时,源码...

    强大的验证码生成库: JCaptchaSourceCode

    总结来说,`JCaptcha`作为一款强大的Java验证码库,其易用性、灵活性和安全性使其成为开发者们的首选。通过学习和实践提供的Web应用示例,开发者可以快速掌握`JCaptcha`的使用方法,并将其成功应用到自己的项目中,...

    Web 开发实现验证码输入功能

    总结来说,Web开发中的验证码输入功能是一个涉及到图像处理、随机数生成、服务器与客户端交互等多个技术领域的复杂过程。通过合理地实现验证码,可以有效地提高网站的安全性,防止恶意自动化操作。而实际的实现方式...

    Maven项目中验证码的实现

    为了使用`jcaptcha`提供的验证码功能,需要配置一个`jcaptcha.xml`文件,该文件定义了验证码服务、存储器以及图片引擎等组件。下面是一个示例配置: ```xml xmlns:xsi=...

    jsp生成中文字符的验证码

    - **绘制验证码**:可以使用Java的Graphics类或者第三方库(如JCaptcha)来绘制验证码图像,包括字符、背景、干扰线等元素。 - **存储与验证**:生成的验证码字符串要存储在服务器端,当用户输入后,服务器会比对...

    j'pajcaptcha

    【jCaptcha简介】 jCaptcha,全称为Java CAPTCHA,是一个基于Java的开源验证码(Completely Automated Public Turing test to ...因此,开发者在使用jCaptcha时,应关注其更新,结合实际场景选择合适的验证码策略。

    spring security3.1 实现验证码自定义登录

    最后,为了方便开发,我们可以使用一些开源的验证码生成工具库,如JCaptcha或Simple Captcha,它们可以简化验证码生成和验证的实现。 总结来说,Spring Security 3.1的验证码自定义登录涉及验证码生成、自定义...

Global site tag (gtag.js) - Google Analytics