Spring Boot实现登录验证码功能的案例详解

Spring Boot实现登录验证码功能的案例详解

简介

最近,我在开发一个基于Spring Boot的Web应用程序时,需要实现一个登录验证码功能,以确保用户输入有效并防止暴力破解。在研究后,我发现可以通过添加一些依赖项和编写一些代码来轻松地实现此功能。在本文中,我将与您分享实现登录验证码功能的详细步骤。

步骤

步骤1:添加依赖

为了实现登录验证码功能,我们需要在Spring Boot项目中添加以下依赖项:

<!-- Spring Boot Web Starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot Thymeleaf Starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<!-- Spring Boot Validation Starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<!-- Google Guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>19.0</version>
</dependency>

<!-- Google Guava图像处理库 -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava-image</artifactId>
    <version>19.0</version>
</dependency>

<!-- 生成随机数工具 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.2.1</version>
</dependency>

步骤2:创建验证码API

为了创建验证码API,我们需要在Spring Boot应用程序中创建一个REST API Endpoint。我们将使用Google Guava创建验证码图像,并将其返回到客户端。以下是我们创建的验证码API:

@RestController
@RequestMapping("/api/v1")
public class CaptchaApiController {

    private final int WIDTH = 100;
    private final int HEIGHT = 35;
    private final int LENGTH = 4;

    private final Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(1000).build();

    @GetMapping(value = "/captcha", produces = MediaType.IMAGE_JPEG_VALUE)
    public ResponseEntity<byte[]> createCaptcha(HttpServletResponse response) throws Exception {
        String captcha = RandomStringUtils.randomAlphanumeric(LENGTH);
        byte[] bytes = createCaptchaImage(captcha);
        cache.put(captcha.toLowerCase(), captcha.toLowerCase());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_JPEG);
        headers.setContentLength(bytes.length);
        return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
    }

    @GetMapping("/captcha/check")
    public boolean checkCaptcha(@RequestParam String captcha) {
        return Strings.isNullOrEmpty(captcha) || !captcha.matches("[a-zA-Z0-9]{4}") || !cache.asMap().containsKey(captcha.toLowerCase());
    }

    private byte[] createCaptchaImage(String captchaText) throws IOException {
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = image.getGraphics();
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, WIDTH, HEIGHT);
        graphics.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 22));
        for (int i = 0; i < captchaText.length(); i++) {
            graphics.setColor(new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255)));
            graphics.drawString(Character.toString(captchaText.charAt(i)), 15 * i + 5, 20 + (int) (10 * Math.random()));
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "jpeg", outputStream);
        return outputStream.toByteArray();
    }

}

根据以上代码,我们可以看到 createCaptcha 返回一个byte数组,这是使用Java的内置API实现验证码图像生成的数据,利用响应头指定响应数据格式为JPEG,它可用作REST服务API进行调用。另外,我们还可以看到 checkCaptcha 用于验证验证码是否匹配。

步骤3:创建验证码表单

我们需要将验证码添加到登录表单中,以便用户输入验证码。以下是我们创建的登录表单:

<form method="post" action="/login">
    <div>
        <label for="username">用户名 :</label>
        <input id="username" type="text" placeholder="请输入用户名" name="username" required="required"/>
    </div>
    <div>
        <label for="password">密码 :</label>
        <input id="password" type="password" placeholder="请输入密码" name="password" required="required"/>
    </div>
    <div>
        <label for="captcha">验证码 :</label>
        <input id="captcha" type="text" placeholder="请输入验证码" name="captcha" required="required"/>
        <img id="captcha-img" alt="验证码" src="/api/v1/captcha"/>
    </div>
    <button type="submit">登录</button>
</form>

在上面的表单中,我们添加了一个图像元素到 img 标记并使用 src 属性设置图像URL。在加载页面时,将调用 api / v1 / captcha 端点来获取验证码图像。除此之外,我们还添加了一个输入框来让用户输入验证码。

步骤4:验证用户

最后,我们需要创建另一个Endpoint,以验证用户输入的用户名、密码和验证码是否正确。以下是我们创建的验证代码:

@PostMapping("/login")
public ModelAndView login(@RequestParam String username, @RequestParam String password, @RequestParam String captcha, HttpSession session) {
    ModelAndView modelAndView = new ModelAndView();
    boolean validCaptcha = !checkCaptcha(captcha);
    boolean validUser = userRepository.existsByUsername(username) && passwordEncoder.matches(password, userRepository.findByUsername(username).getPassword());
    if (validCaptcha && validUser) {
        session.setAttribute("username", username);
        modelAndView.setViewName("redirect:/dashboard");
    } else {
        modelAndView.clear();
        modelAndView.setViewName("redirect:/login");
        modelAndView.addObject("errorMessage", "用户名或密码错误");
    }
    return modelAndView;
}

在上述代码中,我们首先验证验证码是否与 captcha 相同,如果相同,则通过验证。如果验证码验证通过,则验证用户的用户名和密码。如果验证通过,则将其添加到当前会话中,然后将用户重定向到仪表板页面。

示例

为了更好地说明博客文章的内容,请参见以下两个互联网示例::

  1. Java Home Cloud - Spring Boot实现验证码
  2. Spring Boot Captcha App - Github

这些示例提供了一个Spring Boot应用程序,帮助您快速获取有关如何实现登录验证码功能的真实和具体的实现。

结论

在本文中,我们详细探讨了Spring Boot实现图形验证码的方法,并提供了两个示例代码引用供读者参考。使用Spring Boot和其他依赖项,我们可以轻松地实现网站中的验证码功能,以降低暴力攻击和垃圾回收的风险。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot实现登录验证码功能的案例详解 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • java.lang.ExceptionInInitializerError异常的解决方法

    当在Java应用程序中使用静态代码块或静态变量时,可能会出现java.lang.ExceptionInInitializerError异常。该异常是由于在静态代码块或静态变量赋值期间抛出异常而导致的。 在解决此异常的过程中,需要扫描静态块或静态变量的代码,找出其中可能引起错误的部分,并对其进行调试修复。 以下是解决java.lang.ExceptionInI…

    Java 2023年5月27日
    00
  • Spring中事务管理的四种方法(银行转账为例)

    请看我以下的详细讲解。 Spring中事务管理的四种方法 Spring中提供了四种常用的方式来管理事务,分别是: 通过AOP实现声明式事务管理 通过编程式事务管理 通过注解实现声明式事务管理 通过TransactionTemplate实现编程式事务管理 对于每种事务管理方式,我们将通过银行转账的例子进行说明。 1. 通过AOP实现声明式事务管理 在这种方式中…

    Java 2023年5月20日
    00
  • 详解Spring Security中获取当前登录用户的详细信息的几种方法

    下面就来详细讲解一下Spring Security获取当前登录用户的详细信息的几种方法。 1. 使用Authentication对象获取当前登录用户信息 在Spring Security中,用户需要进行身份验证后才能访问受保护的资源。在用户访问受保护的资源时,Spring Security会将用户的认证信息存储在一个名为Authentication的对象中。…

    Java 2023年5月20日
    00
  • JavaWeb中使用JavaMail实现发送邮件功能实例详解

    下面我将为你详细讲解“JavaWeb中使用JavaMail实现发送邮件功能实例详解”的完整攻略。 1. 前置技能 在使用JavaMail之前你需要具备以下知识: Java基础知识:Java语法、类、对象、方法、接口、异常、集合框架等 SMTP/POP3协议:SMTP是发送邮件的协议,POP3是接收邮件的协议,具体可以通过网络搜索或者参考相关文档进行了解 2.…

    Java 2023年6月15日
    00
  • spring 和 spring boot 中的属性配置方式

    Spring和Spring Boot中的属性配置方式 Spring和Spring Boot都提供了多种属性配置方式,本文将详细介绍这些方式,并提供两个示例。 Spring中的属性配置方式 Spring中的属性配置方式有以下几种: 1. 使用XML配置文件 使用XML配置文件是Spring最早的属性配置方式。在XML配置文件中,我们可以使用元素来定义Bean,…

    Java 2023年5月15日
    00
  • 什么是线程安全的并发容器?

    以下是关于线程安全的并发容器的完整使用攻略: 什么是线程安全的并发容器? 线程安全并发容器是指在多线程环境下,多个线程可以同时访问容器中的元素,而不会出现数据不一致或程序崩溃等问题。在多线程编程中,线程安全的并发容器是非常重要的,因为多个线程同时访问容器,会出现线程争用的问题,导致数据不一致或程序崩溃。 如何实现线程安全的并发容器? 为了实现线程安全的并发容…

    Java 2023年5月12日
    00
  • 使用Easyui实现查询条件的后端传递并自动刷新表格的两种方法

    使用EasyUI实现查询条件的后端传递并自动刷新表格,一般有两种方法可以实现。 方法一:使用表单的submit事件以及datagrid的load方法 1. 在页面中定义查询表单以及datagrid 在页面中定义一个查询表单,表单中包含了查询条件,以及一个查询按钮。同时,定义一个datagrid用于表格的展示。 <form id="queryF…

    Java 2023年6月15日
    00
  • javaweb实现文件上传示例代码

    下面是javaweb实现文件上传的完整攻略: 1. 准备工作 在实现文件上传之前,需要先通过一些准备工作来确保程序能够正确运行: 1.1 配置servlet-api.jar文件 确保下载并配置servlet-api.jar文件,该文件包含了用于编写JavaWeb开发的类。 1.2 配置服务器环境 使用基于Java的web服务器(如Tomcat)来运行Java…

    Java 2023年6月2日
    00
合作推广
合作推广
分享本页
返回顶部