springboot怎么集成easy-captcha实现图像验证码显示和登录

发布时间:2023-04-04 17:15:57 作者:iii
来源:亿速云 阅读:235

SpringBoot怎么集成Easy-Captcha实现图像验证码显示和登录

目录

  1. 引言
  2. Easy-Captcha简介
  3. SpringBoot项目搭建
  4. 集成Easy-Captcha
  5. 生成验证码
  6. 验证码显示
  7. 验证码校验
  8. 登录功能实现
  9. 安全性考虑
  10. 总结

引言

在现代Web应用中,验证码(CAPTCHA)是一种常见的安全机制,用于防止自动化脚本或机器人进行恶意操作,如暴力破解、垃圾邮件发送等。验证码通常以图像形式呈现,要求用户输入图像中的字符或数字,以证明其为真实用户。

Spring Boot 是一个用于快速开发Spring应用的框架,它简化了Spring应用的配置和部署过程。Easy-Captcha 是一个简单易用的Java验证码生成库,支持多种验证码类型,如算术验证码、字符验证码等。

本文将详细介绍如何在Spring Boot项目中集成Easy-Captcha,实现图像验证码的生成、显示和校验,并结合登录功能,提升应用的安全性。

Easy-Captcha简介

Easy-Captcha 是一个基于Java的验证码生成库,支持多种验证码类型,包括:

Easy-Captcha 提供了简单的API,易于集成到Spring Boot项目中,并且支持自定义验证码的样式、大小、颜色等。

SpringBoot项目搭建

在开始集成Easy-Captcha之前,首先需要搭建一个Spring Boot项目。可以使用Spring Initializr快速生成项目骨架。

1. 创建Spring Boot项目

访问 Spring Initializr,选择以下配置:

Dependencies 中添加以下依赖:

点击 Generate 下载项目压缩包,解压后导入到IDE中。

2. 项目结构

项目结构如下:

captcha-demo
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           └── captchademo
│   │   │               ├── CaptchaDemoApplication.java
│   │   │               ├── controller
│   │   │               │   └── CaptchaController.java
│   │   │               ├── service
│   │   │               │   └── CaptchaService.java
│   │   │               └── config
│   │   │                   └── WebConfig.java
│   │   └── resources
│   │       ├── static
│   │       ├── templates
│   │       │   └── index.html
│   │       └── application.properties
│   └── test
│       └── java
│           └── com
│               └── example
│                   └── captchademo
└── pom.xml

3. 配置application.properties

src/main/resources/application.properties 中添加以下配置:

# Server port
server.port=8080

# Thymeleaf configuration
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

集成Easy-Captcha

1. 添加Easy-Captcha依赖

pom.xml 中添加Easy-Captcha的依赖:

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

2. 配置WebConfig

src/main/java/com/example/captchademo/config/WebConfig.java 中配置Web相关的Bean,如静态资源处理、拦截器等。

package com.example.captchademo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/");
    }
}

生成验证码

1. 创建CaptchaService

src/main/java/com/example/captchademo/service/CaptchaService.java 中创建 CaptchaService,用于生成验证码。

package com.example.captchademo.service;

import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.base.Captcha;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Service
public class CaptchaService {

    public void generateCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 设置响应头
        response.setContentType("image/png");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        // 生成算术验证码
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(130, 48);
        captcha.setLen(2);  // 几位数运算,默认是两位
        captcha.getArithmeticString();  // 获取运算的公式:3+2=?

        // 获取验证码结果
        String result = captcha.text();

        // 将验证码结果存入session
        HttpSession session = request.getSession();
        session.setAttribute("captcha", result);

        // 输出验证码图片
        captcha.out(response.getOutputStream());
    }
}

2. 创建CaptchaController

src/main/java/com/example/captchademo/controller/CaptchaController.java 中创建 CaptchaController,用于处理验证码生成请求。

package com.example.captchademo.controller;

import com.example.captchademo.service.CaptchaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
public class CaptchaController {

    @Autowired
    private CaptchaService captchaService;

    @GetMapping("/captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        captchaService.generateCaptcha(request, response);
    }
}

验证码显示

1. 创建前端页面

src/main/resources/templates/index.html 中创建前端页面,用于显示验证码和登录表单。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
    <link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
    <div class="login-container">
        <h2>用户登录</h2>
        <form action="/login" method="post">
            <div class="form-group">
                <label for="username">用户名</label>
                <input type="text" id="username" name="username" required>
            </div>
            <div class="form-group">
                <label for="password">密码</label>
                <input type="password" id="password" name="password" required>
            </div>
            <div class="form-group">
                <label for="captcha">验证码</label>
                <input type="text" id="captcha" name="captcha" required>
                <img src="/captcha" alt="验证码" onclick="refreshCaptcha()">
            </div>
            <button type="submit">登录</button>
        </form>
    </div>

    <script>
        function refreshCaptcha() {
            document.querySelector('img').src = '/captcha?t=' + new Date().getTime();
        }
    </script>
</body>
</html>

2. 添加样式

src/main/resources/static/css/style.css 中添加样式:

body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}

.login-container {
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    width: 300px;
}

h2 {
    text-align: center;
    margin-bottom: 20px;
}

.form-group {
    margin-bottom: 15px;
}

label {
    display: block;
    margin-bottom: 5px;
}

input {
    width: 100%;
    padding: 8px;
    box-sizing: border-box;
    border: 1px solid #ccc;
    border-radius: 4px;
}

button {
    width: 100%;
    padding: 10px;
    background-color: #28a745;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button:hover {
    background-color: #218838;
}

img {
    cursor: pointer;
    margin-left: 10px;
}

验证码校验

1. 修改CaptchaController

CaptchaController 中添加验证码校验的逻辑。

package com.example.captchademo.controller;

import com.example.captchademo.service.CaptchaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
public class CaptchaController {

    @Autowired
    private CaptchaService captchaService;

    @GetMapping("/captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        captchaService.generateCaptcha(request, response);
    }

    @GetMapping("/")
    public String index() {
        return "index";
    }

    @PostMapping("/login")
    public String login(String username, String password, String captcha, HttpServletRequest request, Model model) {
        HttpSession session = request.getSession();
        String sessionCaptcha = (String) session.getAttribute("captcha");

        if (sessionCaptcha == null || !sessionCaptcha.equals(captcha)) {
            model.addAttribute("error", "验证码错误");
            return "index";
        }

        // 模拟登录逻辑
        if ("admin".equals(username) && "123456".equals(password)) {
            model.addAttribute("username", username);
            return "welcome";
        } else {
            model.addAttribute("error", "用户名或密码错误");
            return "index";
        }
    }
}

2. 创建欢迎页面

src/main/resources/templates/welcome.html 中创建欢迎页面。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>欢迎页面</title>
    <link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
    <div class="welcome-container">
        <h2>欢迎, <span th:text="${username}"></span>!</h2>
        <a href="/">返回登录</a>
    </div>
</body>
</html>

登录功能实现

1. 模拟用户登录

CaptchaController 中,我们已经实现了简单的登录逻辑。用户名为 admin,密码为 123456 时,登录成功并跳转到欢迎页面。

2. 处理登录失败

如果验证码错误或用户名密码错误,返回登录页面并显示错误信息。

@PostMapping("/login")
public String login(String username, String password, String captcha, HttpServletRequest request, Model model) {
    HttpSession session = request.getSession();
    String sessionCaptcha = (String) session.getAttribute("captcha");

    if (sessionCaptcha == null || !sessionCaptcha.equals(captcha)) {
        model.addAttribute("error", "验证码错误");
        return "index";
    }

    // 模拟登录逻辑
    if ("admin".equals(username) && "123456".equals(password)) {
        model.addAttribute("username", username);
        return "welcome";
    } else {
        model.addAttribute("error", "用户名或密码错误");
        return "index";
    }
}

安全性考虑

1. 验证码有效期

验证码应设置有效期,防止长时间未使用的验证码被恶意利用。可以在生成验证码时记录生成时间,并在校验时检查是否过期。

// 生成验证码时记录时间
session.setAttribute("captchaTime", System.currentTimeMillis());

// 校验验证码时检查时间
long captchaTime = (long) session.getAttribute("captchaTime");
if (System.currentTimeMillis() - captchaTime > 60 * 1000) {  // 1分钟有效期
    model.addAttribute("error", "验证码已过期");
    return "index";
}

2. 防止暴力破解

为了防止暴力破解,可以限制验证码的尝试次数。例如,在Session中记录验证码错误次数,超过一定次数后锁定账户或要求重新生成验证码。

// 记录错误次数
int errorCount = (int) session.getAttribute("errorCount");
if (errorCount >= 3) {
    model.addAttribute("error", "验证码错误次数过多,请刷新验证码");
    return "index";
}

// 错误次数加1
session.setAttribute("errorCount", errorCount + 1);

3. 防止CSRF攻击

为了防止CSRF攻击,可以在表单中添加CSRF令牌,并在服务器端进行校验。

<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">

总结

本文详细介绍了如何在Spring Boot项目中集成Easy-Captcha,实现图像验证码的生成、显示和校验,并结合登录功能,提升应用的安全性。通过本文的步骤,您可以轻松地在自己的Spring Boot项目中添加验证码功能,防止自动化脚本的恶意操作。

验证码是Web应用安全的重要组成部分,但并不是唯一的安全措施。在实际应用中,还应结合其他安全机制,如HTTPS、密码加密、防止SQL注入等,全面提升应用的安全性。

希望本文对您有所帮助,祝您在Spring Boot开发中取得更多成果!

推荐阅读:
  1. SSL自制证书、springboot使用的示例分析
  2. 微服务springcloud springboot 框架源码 activiti工作流 前后分离

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot

上一篇:C++怎么改变参数值

下一篇:Vue3.0中ElementPlus<input输入框自动获取焦点>问题怎么解决

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》