返回

无痛集成 easy-captcha,为 Java21 + SpringBoot3 项目护航

后端

在当今网络安全形势日益严峻的背景下,验证码作为一道不可或缺的安全屏障,在防止恶意攻击和机器人刷量方面发挥着至关重要的作用。然而,繁琐的验证码集成过程往往让开发人员头疼不已。

针对这一痛点,easy-captcha 应运而生。这款轻量级的 Java 验证码框架凭借其简单易用的特性,迅速俘获了开发者的芳心。本文将循序渐进地指导您,如何将 easy-captcha 无痛集成到 Java21 + SpringBoot3 项目中,轻松实现验证码显示和登录校验。

相关技术简介

  • Java21: Java 编程语言的最新版本,提供了诸多新特性和性能优化。
  • SpringBoot3: 备受欢迎的 Spring 框架的最新版本,集成了对 Java21 的支持,简化了 Web 应用的开发。
  • easy-captcha: 一款轻量级、可扩展的 Java 验证码框架,支持多种验证码类型和丰富的配置选项。

easy-captcha 实现步骤

1. 引入 Maven 依赖

在项目的 pom.xml 文件中添加 easy-captcha 依赖:

<dependency>
    <groupId>com.github.whvcse</groupId>
    <artifactId>easy-captcha</artifactId>
    <version>2.1.4</version>
</dependency>

2. 定义实体类

创建一个实体类用于存储验证码信息:

@Entity
@Table(name = "captcha")
public class Captcha {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String code;

    private LocalDateTime expireTime;

}

3. 定义登录服务类

创建登录服务类实现验证码校验:

@Service
public class LoginService {

    @Autowired
    private CaptchaRepository captchaRepository;

    public boolean verifyCaptcha(String captchaCode) {
        // 根据验证码获取记录
        Captcha captcha = captchaRepository.findByCode(captchaCode);

        // 判断验证码是否过期
        if (captcha == null || captcha.getExpireTime().isBefore(LocalDateTime.now())) {
            return false;
        }

        // 删除验证码记录
        captchaRepository.delete(captcha);

        return true;
    }

}

4. 定义登录控制器

创建登录控制器接收用户请求:

@Controller
@RequestMapping("/login")
public class LoginController {

    @Autowired
    private LoginService loginService;

    @PostMapping
    public String login(@RequestParam String username, @RequestParam String password, @RequestParam String captchaCode) {
        if (!loginService.verifyCaptcha(captchaCode)) {
            // 验证码错误
            return "redirect:/login?error=captcha";
        }

        // 校验用户名和密码
        if (username.equals("admin") && password.equals("123456")) {
            // 登录成功
            return "redirect:/home";
        }

        // 登录失败
        return "redirect:/login?error=login";
    }

}

5. 前端登录页面实现

在前端登录页面集成 easy-captcha 组件:

<form action="/login" method="post">
    <input type="text" name="username" placeholder="用户名">
    <input type="password" name="password" placeholder="密码">
    <div id="captcha"></div>
    <input type="text" name="captchaCode" placeholder="验证码">
    <button type="submit">登录</button>
</form>

<script src="https://unpkg.com/easy-captcha"></script>
<script>
    const captcha = new EasyCaptcha();
    captcha.render('captcha');
</script>

6. 测试和验证

运行项目并访问登录页面,点击刷新验证码按钮,即可生成新的验证码。输入用户名、密码和验证码,点击登录按钮进行校验。如果验证码错误或已过期,将提示验证码错误;如果用户名和密码正确,则登录成功。

总结

通过本文的循序渐进指导,您已经成功将 easy-captcha 集成到 Java21 + SpringBoot3 项目中,实现了验证码显示和登录校验。easy-captcha 的简便性和可扩展性,将大大提升您的开发效率,助力构建更安全可靠的 Web 应用。

附录

1. 使用 Session 缓存验证码

为了防止频繁请求验证码对后端造成压力,可以在 Session 中缓存验证码:

@RestController
@RequestMapping("/captcha")
public class CaptchaController {

    @Autowired
    private CaptchaRepository captchaRepository;

    @GetMapping("/get")
    public Captcha getCaptcha() {
        // 根据 Session 获取验证码
        Captcha captcha = (Captcha) session.getAttribute("captcha");

        // 验证码已存在,直接返回
        if (captcha != null) {
            return captcha;
        }

        // 生成新的验证码
        captcha = new Captcha();
        captcha.setCode(captchaService.generateCaptchaCode());
        captcha.setExpireTime(LocalDateTime.now().plusMinutes(1));

        // 将验证码保存到 Session 和数据库中
        session.setAttribute("captcha", captcha);
        captchaRepository.save(captcha);

        return captcha;
    }

}

2. 前端登录

<form action="/login" method="post">
    <input type="text" name="username" placeholder="用户名">
    <input type="password" name="password" placeholder="密码">
    <img src="/captcha/get" alt="验证码" id="captchaImage" onclick="refreshCaptcha()">
    <input type="text" name="captchaCode" placeholder="验证码">
    <button type="submit">登录</button>
</form>

<script>
    function refreshCaptcha() {
        document.getElementById("captchaImage").src = "/captcha/get?t=" + new Date().getTime();
    }
</script>