Spring Boot如何实现登录验证码功能

发布时间:2022-08-10 14:31:59 作者:iii
来源:亿速云 阅读:409

Spring Boot如何实现登录验证码功能

目录

  1. 引言
  2. 验证码的作用
  3. Spring Boot简介
  4. 实现登录验证码功能的步骤
    1. 创建Spring Boot项目
    2. 添加依赖
    3. 配置验证码生成器
    4. 生成验证码
    5. 验证码的存储与验证
    6. 前端集成验证码
    7. 登录接口的改造
  5. 代码实现
    1. 验证码生成器
    2. 验证码存储与验证
    3. 前端页面
    4. 登录接口
  6. 测试与验证
  7. 常见问题与解决方案
  8. 总结

引言

在现代Web应用中,登录验证码功能是防止恶意登录、暴力破解密码等安全威胁的重要手段之一。通过引入验证码,可以有效防止自动化脚本的恶意攻击,提升系统的安全性。本文将详细介绍如何在Spring Boot项目中实现登录验证码功能。

验证码的作用

验证码(CAPTCHA)是一种区分用户是计算机还是人的公共全自动程序。它可以有效防止恶意用户通过自动化脚本进行暴力破解、垃圾注册、恶意刷票等行为。常见的验证码类型包括数字验证码、字母验证码、图形验证码、滑动验证码等。

Spring Boot简介

Spring Boot是一个基于Spring框架的快速开发框架,它简化了Spring应用的初始搭建和开发过程。通过自动配置和约定优于配置的原则,Spring Boot使得开发者能够快速构建独立运行的、生产级别的Spring应用。

实现登录验证码功能的步骤

创建Spring Boot项目

首先,我们需要创建一个Spring Boot项目。可以通过Spring Initializr(https://start.spring.io/)快速生成一个Spring Boot项目。选择Maven或Gradle作为构建工具,并添加必要的依赖。

添加依赖

pom.xml文件中添加以下依赖:

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

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

    <!-- Spring Boot Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <!-- Google Kaptcha -->
    <dependency>
        <groupId>com.github.axet</groupId>
        <artifactId>kaptcha</artifactId>
        <version>0.0.9</version>
    </dependency>
</dependencies>

配置验证码生成器

我们将使用Google的Kaptcha库来生成验证码。Kaptcha是一个简单易用的验证码生成库,支持多种验证码样式。

application.properties文件中添加Kaptcha的配置:

# Kaptcha配置
kaptcha.border=yes
kaptcha.border.color=105,179,90
kaptcha.textproducer.font.color=blue
kaptcha.textproducer.font.size=45
kaptcha.textproducer.char.length=4
kaptcha.textproducer.char.space=2
kaptcha.image.width=200
kaptcha.image.height=50

生成验证码

接下来,我们需要创建一个验证码生成器。通过Kaptcha库,我们可以轻松生成验证码图片。

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

@Configuration
public class KaptchaConfig {

    @Bean
    public DefaultKaptcha getDefaultKaptcha() {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        properties.setProperty("kaptcha.border", "yes");
        properties.setProperty("kaptcha.border.color", "105,179,90");
        properties.setProperty("kaptcha.textproducer.font.color", "blue");
        properties.setProperty("kaptcha.textproducer.font.size", "45");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        properties.setProperty("kaptcha.textproducer.char.space", "2");
        properties.setProperty("kaptcha.image.width", "200");
        properties.setProperty("kaptcha.image.height", "50");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

验证码的存储与验证

生成验证码后,我们需要将其存储在服务器端,并在用户提交登录请求时进行验证。通常,我们可以将验证码存储在Session中。

import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;

@Controller
public class CaptchaController {

    @Autowired
    private Producer captchaProducer;

    @GetMapping("/captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        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");

        String capText = captchaProducer.createText();
        HttpSession session = request.getSession();
        session.setAttribute("captcha", capText);

        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
}

前端集成验证码

在前端页面中,我们需要显示验证码图片,并允许用户输入验证码。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h2>Login</h2>
    <form th:action="@{/login}" method="post">
        <div>
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required>
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required>
        </div>
        <div>
            <label for="captcha">Captcha:</label>
            <input type="text" id="captcha" name="captcha" required>
            <img src="/captcha" onclick="this.src='/captcha?'+Math.random()" alt="Captcha">
        </div>
        <div>
            <button type="submit">Login</button>
        </div>
    </form>
</body>
</html>

登录接口的改造

最后,我们需要改造登录接口,使其在验证用户名和密码之前,先验证用户输入的验证码是否正确。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
public class LoginController {

    @PostMapping("/login")
    public String login(@RequestParam String username,
                        @RequestParam String password,
                        @RequestParam String captcha,
                        HttpServletRequest request) {
        HttpSession session = request.getSession();
        String sessionCaptcha = (String) session.getAttribute("captcha");
        if (sessionCaptcha == null || !sessionCaptcha.equalsIgnoreCase(captcha)) {
            return "redirect:/login?error=captcha";
        }

        // 验证用户名和密码
        // ...

        return "redirect:/home";
    }
}

代码实现

验证码生成器

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

@Configuration
public class KaptchaConfig {

    @Bean
    public DefaultKaptcha getDefaultKaptcha() {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        properties.setProperty("kaptcha.border", "yes");
        properties.setProperty("kaptcha.border.color", "105,179,90");
        properties.setProperty("kaptcha.textproducer.font.color", "blue");
        properties.setProperty("kaptcha.textproducer.font.size", "45");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        properties.setProperty("kaptcha.textproducer.char.space", "2");
        properties.setProperty("kaptcha.image.width", "200");
        properties.setProperty("kaptcha.image.height", "50");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

验证码存储与验证

import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;

@Controller
public class CaptchaController {

    @Autowired
    private Producer captchaProducer;

    @GetMapping("/captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        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");

        String capText = captchaProducer.createText();
        HttpSession session = request.getSession();
        session.setAttribute("captcha", capText);

        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
}

前端页面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h2>Login</h2>
    <form th:action="@{/login}" method="post">
        <div>
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required>
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required>
        </div>
        <div>
            <label for="captcha">Captcha:</label>
            <input type="text" id="captcha" name="captcha" required>
            <img src="/captcha" onclick="this.src='/captcha?'+Math.random()" alt="Captcha">
        </div>
        <div>
            <button type="submit">Login</button>
        </div>
    </form>
</body>
</html>

登录接口

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
public class LoginController {

    @PostMapping("/login")
    public String login(@RequestParam String username,
                        @RequestParam String password,
                        @RequestParam String captcha,
                        HttpServletRequest request) {
        HttpSession session = request.getSession();
        String sessionCaptcha = (String) session.getAttribute("captcha");
        if (sessionCaptcha == null || !sessionCaptcha.equalsIgnoreCase(captcha)) {
            return "redirect:/login?error=captcha";
        }

        // 验证用户名和密码
        // ...

        return "redirect:/home";
    }
}

测试与验证

在完成上述步骤后,我们可以启动Spring Boot应用,并访问登录页面。在输入用户名、密码和验证码后,系统会验证验证码是否正确。如果验证码错误,用户将被重定向回登录页面并显示错误信息。

常见问题与解决方案

  1. 验证码不显示:检查Kaptcha配置是否正确,确保/captcha接口能够正常访问。
  2. 验证码验证失败:确保验证码生成和验证时使用的是同一个Session,并且验证码存储和验证的逻辑正确。
  3. 验证码刷新问题:在前端页面中,通过onclick事件刷新验证码图片,确保每次请求都能获取到新的验证码。

总结

通过本文的介绍,我们详细讲解了如何在Spring Boot项目中实现登录验证码功能。验证码的引入可以有效防止恶意登录和暴力破解,提升系统的安全性。希望本文能够帮助你在实际项目中顺利实现登录验证码功能。

推荐阅读:
  1. Spring Boot集成Spring Security实现OAuth 2.0登录
  2. spring-boot中登录过滤功能如何实现

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

springboot

上一篇:JWT登录认证实例分析

下一篇:v-bind如何动态绑定class属性

相关阅读

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

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