captcha

验证码是什么

验证码(captcha)一种能自动区分计算机和人类用户的公开图灵测试(Completely AutomatedPublic Turing test to tell Computers and Humans Apart, CAPTCHA),它的生成和评测都不需要人的干预,底层数据库和算法公开,人类很容易通过但计算机程序几乎不能通过。最早出现在雅虎,是为了解决自己和用户们每天遇到的垃圾邮件轰炸问题。

验证码有什么用

网站安全方面,它防止程序进行垃圾注册滥用资源,防止恶意登录和账号盗用,为用户的账号安全提供保障。
数据安全方面,验证码作为阻挡数据爬取、防止数据被破坏的一道屏障起了重要作用。
运营安全方面,它阻碍恶意刷单现象、防止虚假秒杀、虚假评论,保障投票结果的真实性。
交易安全方面,它阻挡虚假交易、恶意套现、盗卡支付等行为,为交易支付保驾护航。

kaptcha简介

kaptcha 是一个很有用的验证码生成工具,由于它有许多可配置项,所以用它可以简单快捷的生成各式各样的验证码。

开发工具及使用的核心技术

  1. IntelliJ IDEA
  2. Spring Boot
  3. React
  4. kaptcha

    快速入门

  5. 添加依赖
    compile("com.github.penggle:kaptcha:2.3.2")
  6. 配置kaptcha

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @Configuration
    public class KaptchaConfig {
    @Bean
    public DefaultKaptcha getDefaultKaptcha(){
    DefaultKaptcha captchaProducer = new DefaultKaptcha();
    Properties properties = new Properties();
    properties.setProperty("kaptcha.border", "no");
    properties.setProperty("kaptcha.textproducer.font.color", "blue");
    properties.setProperty("kaptcha.textproducer.font.size", "30");
    properties.setProperty("kaptcha.image.width", "110");
    properties.setProperty("kaptcha.image.height", "40");
    properties.setProperty("kaptcha.session.key", "code");
    properties.setProperty("kaptcha.textproducer.char.length", "4");
    properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
    Config config = new Config(properties);
    captchaProducer.setConfig(config);
    return captchaProducer;
    }
    }
  7. 编写controller用于生成验证码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    @RestController
    public class CodeController {
    @Autowired
    private Producer captchaProducer;
    public static String code = "";
    @GetMapping("/kaptcha")
    public void getKaptchaImage(HttpServletResponse response) throws Exception {
    response.setDateHeader("Expires", 0);
    response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
    response.addHeader("Cache-Control", "post-check=0, pre-check=0");
    response.setHeader("Pragma", "no-cache");
    response.setContentType("image/jpeg");
    code = captchaProducer.createText();
    BufferedImage bi = captchaProducer.createImage(code);
    ServletOutputStream out = response.getOutputStream();
    ImageIO.write(bi, "jpg", out);
    try {
    out.flush();
    } finally {
    out.close();
    }
    }
    }

注:在这个controller中注入第2步中配置的那个bean,然后就可以使用它生成验证码并保存在静态变量code中,以及向客户端输出图片类型的验证码;

  1. 验证码对比工具
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class CodeUtil {
    public static boolean checkVerifyCode(String verifyCodeActual) {
    if(CodeController.code==null || CodeController.code.equals(""))
    return false;
    if (!verifyCodeActual.equals(CodeController.code)) {
    return false;
    }
    return true;
    }
    }

注:这个类用来比对生成的验证码与用户输入的验证码是否一致。

  1. 使用验证码登陆
    在/login接口中,验证用户前调用第4步工具类判断验证码是否一致

    1
    2
    3
    if (!CodeUtil.checkVerifyCode(request.getCaptcha())) {
    throw new UserException("验证码错误");
    }
  2. 验证码前端使用
    <img alt="点击更换" title="点击更换" src="http://localhost:8080/kaptcha" />
    注:因为进行了前后端服务拆分,所以此处src为本地图片验证码生产接口。