博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
学会这个工具的使用,让你快速生成验证码
阅读量:6192 次
发布时间:2019-06-21

本文共 6549 字,大约阅读时间需要 21 分钟。

前言

验证码是我们做人机验证最常用的方式,常用于敏感操作的验证,比如:登录、注册、修改等。

验证码的原理:不同的客户端拥有不同的 session 对象,在看到验证码图片的时刻,服务器后端代码生成图片并将随机字符存储到 session 中。这样客户端看到的只能是图片,人工识别图片后将字符发送到服务器与 session 中的字符进行比对。

上面只是简单的介绍了验证码的原理,更多细节还需有 javaweb 相关基础知识,这篇文章适合有基础的同学。

最近几天我翻到了以前生成验证码的工具类,使用 Graphics2D 生成的图片,然后再以流的形式写出到客户端,这些代码还是有些问题的,都是硬编码。在以后的使用中我们可能有不同的需求都会导致代码重新修改,自定义一些样式都不是很方便。

所以我找到了 github 上的一个生成验证码的工具:kaptcha,下面我就给大家介绍一下 kaptcha 的使用。

kaptcha 的使用

我们就以一个 maven 构建的 web 项目为例

1、依赖 jar 包

在 pom.xml 文件中添加相关依赖

com.github.penggle
kaptcha
2.3.2

2、配置生成验证码的 servlet

修改 web.xml,添加 kaptcha 提供的 servlet 并配置映射路径

Kaptcha
com.google.code.kaptcha.servlet.KaptchaServlet
Kaptcha
/captcha

访问 这时发现就已经可以产生验证码了,但还有个问题,验证码的随机字符存在哪里了?

3、探索 kaptcha

我们来查看 KaptchaServlet 这个类的源码,doGet 方法

@Overridepublic void doGet(HttpServletRequest req, HttpServletResponse resp)        throws ServletException, IOException{    // Set to expire far in the past.    resp.setDateHeader("Expires", 0);    // Set standard HTTP/1.1 no-cache headers.    resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");    // Set IE extended HTTP/1.1 no-cache headers (use addHeader).    resp.addHeader("Cache-Control", "post-check=0, pre-check=0");    // Set standard HTTP/1.0 no-cache header.    resp.setHeader("Pragma", "no-cache");    // return a jpeg    resp.setContentType("image/jpeg");    // create the text for the image    String capText = this.kaptchaProducer.createText();    // store the text in the session    req.getSession().setAttribute(this.sessionKeyValue, capText);    // store the date in the session so that it can be compared    // against to make sure someone hasn't taken too long to enter    // their kaptcha    req.getSession().setAttribute(this.sessionKeyDateValue, new Date());    // create the image with the text    BufferedImage bi = this.kaptchaProducer.createImage(capText);    ServletOutputStream out = resp.getOutputStream();    // write the data out    ImageIO.write(bi, "jpg", out);}

有这样一段代码,获取字符后存入 session 中,键为 sessionKeyValue 这个变量的值

// create the text for the imageString capText = this.kaptchaProducer.createText();// store the text in the sessionreq.getSession().setAttribute(this.sessionKeyValue, capText);

sessionKeyValue 这个变量的值在 init 方法中被赋值

this.sessionKeyValue = config.getSessionKey();

好我们进入 config.getSessionKey() 中查看代码,发现 session 的键为 Constants 这个类中的常量 Constants.KAPTCHA_SESSION_KEY

return this.properties.getProperty(Constants.KAPTCHA_SESSION_CONFIG_KEY, Constants.KAPTCHA_SESSION_KEY);

4、编写测试验证码是否正常使用的 servlet

我们来验证一下,编写一个 servlet

import com.google.code.kaptcha.Constants;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;@WebServlet("/test")public class TestKaptchaServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        resp.setContentType("text/html;charset=utf-8");        PrintWriter out = resp.getWriter();        //获取传入的验证码        String captcha = req.getParameter("captcha");        if (null != captcha) {            //获取实际session中的验证码            String code = (String) req.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);            if (null == code){                resp.sendRedirect("/captcha");                return;            }            if (code.equalsIgnoreCase(captcha)) {                out.print("验证输入正确");            } else {                out.print("验证码输入有误");            }        } else {            out.print("必须输入验证码");        }        out.flush();        out.close();    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        this.doGet(req, resp);    }}

先访问验证码 然后访问 验证码

以上这些默认配置能满足一般业务的使用了,下面通过深入解析 kaptcha 的源码自定义配置验证码的宽、高、边框、颜色、字符等

5、深入源码自定义配置 kaptcha

再来看一下 init 方法中的代码

@Overridepublic void init(ServletConfig conf) throws ServletException{    super.init(conf);    // Switch off disk based caching.    ImageIO.setUseCache(false);    Enumeration
initParams = conf.getInitParameterNames(); while (initParams.hasMoreElements()) { String key = (String) initParams.nextElement(); String value = conf.getInitParameter(key); this.props.put(key, value); } Config config = new Config(this.props); this.kaptchaProducer = config.getProducerImpl(); this.sessionKeyValue = config.getSessionKey(); this.sessionKeyDateValue = config.getSessionDate();}

这段代码获取 servlet 的初始化参数,并将参数存入 config 对象中,看 config 中的一段代码

public boolean isBorderDrawn(){    String paramName = Constants.KAPTCHA_BORDER;    String paramValue = this.properties.getProperty(paramName);    return this.helper.getBoolean(paramName, paramValue, true);}

没错,所有的参数名字都是 Constants 类中常量名称

public class Constants{    public final static String KAPTCHA_SESSION_KEY = "KAPTCHA_SESSION_KEY";    public final static String KAPTCHA_SESSION_DATE = "KAPTCHA_SESSION_DATE";    public final static String KAPTCHA_SESSION_CONFIG_KEY = "kaptcha.session.key";        //省略其他代码}

所以,可以给 KaptchaServlet 在 web.xml 配置参数,下面这些配置给大家参考

Kaptcha
com.google.code.kaptcha.servlet.KaptchaServlet
kaptcha.border
no
kaptcha.textproducer.font.color
red
kaptcha.image.width
135
kaptcha.textproducer.char.string
ACDEFHKPRSTWX345679
kaptcha.image.height
50
kaptcha.textproducer.font.size
38
kaptcha.noise.color
black
kaptcha.textproducer.char.length
6
kaptcha.textproducer.font.names
Arial
Kaptcha
/captcha

转载地址:http://nerda.baihongyu.com/

你可能感兴趣的文章
iOS开发库的族“.NET研究”谱介绍
查看>>
图解DevExpress RichEditControl富文本的使用,附源码及官方API
查看>>
ubuntu 学习笔记
查看>>
BNU 34986 Football on Table
查看>>
三级联动---城市地区选择
查看>>
webpack插件html-webpack-plugin
查看>>
Git各种错误操作撤销的方法
查看>>
剖析 Laravel 计划任务--避免重复
查看>>
公司框架遇到的问题
查看>>
详解 Discuz 的 PHP经典加密解密函数 authcode
查看>>
vmware station中 UDEV 无法获取共享存储磁盘的UUID,症状: scsi_id -g -u -d /dev/sdb 无返回结果。...
查看>>
Mysql XX 天之内
查看>>
构建插件式的应用程序框架(四)----服务容器
查看>>
AE创建气泡式的提示框(VB.Net和C#源码)
查看>>
Oracle如何删除表中重复记录
查看>>
中科院宣布自研5G基带等关键芯片:替代进口产品
查看>>
尝试使用 LiveWriter写日志
查看>>
TCP 状态字段(SYN, FIN, ACK, PSH, RST, URG)详解
查看>>
magento性能优化.magento速度优化
查看>>
Application Bar
查看>>