集成nanocaptcha库生成登录验证码

背景

需要实现一个验证码登录的功能需求。这个需求挺简单的,主要实现验证码图片生成给前端,然后,在登录接口比对验证码即可。刚拿到这个需求,好久没有搞过登录这一块了,所以,查了一下相关验证码的知识。下面是维基百科中关于验证码的说明:

全自动区分计算机和人类的图灵测试(英语:Completely Automated Public Turing test to tell Computers and Humans Apart,简称CAPTCHA),又称验证码,是一种区分用户是机器或人类的公共全自动程序。在CAPTCHA测试中,作为服务器的计算机会自动生成一个问题由用户来解答。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于机器无法解答CAPTCHA的问题,回答出问题的用户即可视为人类。

原来是大名鼎鼎的图灵测试,真高级。现在2022年这个时间点,最出名的验证码是Google的reCAPTCHA,但是在国内是无法集成使用的。面对这个问题,著名CDN cloudflare是换了hCaptcha进行验证。可以看一看,这篇文章《从 reCAPTCHA 迁移到 hCaptcha》。看了看hCaptcha官网,看样子也是要收费的。有没有一款,免费,不用连外网,还支持JDK17的简单验证码库类?那,下面就来尝试一下:NanoCaptcha。

步骤

Maven

<dependency>
  <groupId>net.logicsquad</groupId>
  <artifactId>nanocaptcha</artifactId>
  <version>1.3</version>
</dependency>

生成验证码图片

    public BufferedImage getCaptcha(HttpSession session) {
        ImageCaptcha imageCaptcha = new ImageCaptcha.Builder(200, 50).addFilter().addBorder().addNoise().addBackground().addContent().build();
        // 保存验证码到当前会话
        String content = imageCaptcha.getContent();
        session.setAttribute(CAPTCHA_KEY, content);
        // 返回图片
        return imageCaptcha.getImage();
    }

这里核心代码就一行:ImageCaptcha imageCaptcha = new ImageCaptcha.Builder(200, 50).addFilter().addBorder().addNoise().addBackground().addContent().build();使用NanoCaptcha生成验证码图片。
然后,将正确的验证码保存到Spring的集中会话中。最后,返回BufferedImage给请求。Controll方法类似如下:

    @GetMapping(value = "/captcha", produces = "image/png")
    public BufferedImage getCaptcha(HttpSession session){
        return userService.getCaptcha(session);
    }

要想Spring正常返回BufferdImage图片,还得注册个Bean,如下:

    @Bean
    public HttpMessageConverter<BufferedImage> bufferedImageHttpMessageConverter() {
        return new BufferedImageHttpMessageConverter();
    }

登录验证

@Override
    public ResponseEntity<Result> authenticateUser(@Valid @RequestBody LoginRequest loginRequest, HttpSession httpSession)  {

        // 验证验证码是否正确
        String content = (String) httpSession.getAttribute(CAPTCHA_KEY);
        httpSession.removeAttribute(CAPTCHA_KEY);
        if (!(StringUtils.hasText(content) && content.equals(loginRequest.getCaptcha()))) {
            throw new MyException("验证码验证失败");
        }
        ...
   }

这里主要就是从会话取出之前生成的正确验证码,与前端提交的验证码进行比对。
**注意:**从会话中读到正确的验证码之后,要从会话中删除掉这个数据。

测试

获取验证码接口:
获取验证码

总结

在使用NanoCaptcha库之前,还尝试使用了BotDetect库,但是BotDetect不支持JDK17就放弃了。而且BotDetect本身自己说Java版本也是测试版本,再加上这边也只需要一款简单够用的验证码就可以了。

参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值