首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Spring Boot 实现登录验证码有效时间

Spring Boot 实现登录验证码有效时间

原创
作者头像
繁依Fanyi
发布于 2024-09-21 03:28:39
发布于 2024-09-21 03:28:39
5150
举报

在现代 Web 应用中,为了提高安全性,登录过程中常常会引入验证码(CAPTCHA)以防止恶意的自动化攻击。然而,简单的验证码并不足够,为了进一步增强安全性,我们通常会为验证码设置有效时间,即验证码只能在生成后的某一段时间内使用,过期后需重新获取。在本文中,我们将以 Spring Boot 为例,详细讲解如何实现带有效时间的登录验证码系统。

一、为什么需要验证码有效时间

验证码通常用于防范暴力破解攻击或机器人自动提交表单。但如果验证码的有效期过长,黑客可能有足够的时间通过试探来破解验证码。因此,为了提升安全性,给验证码设定一个合理的有效期是十分必要的。如果验证码过期,用户需要重新生成验证码。这不仅增加了攻击者破解的难度,还能够提高系统的防御能力。

二、项目结构设计

为了实现验证码的有效时间管理,我们可以采取以下步骤:

  1. 生成验证码并将其存储(通常存储在 Redis 之类的缓存系统中)。
  2. 在存储验证码时,将生成时间一同存储。
  3. 当用户提交验证码时,验证验证码的有效性和正确性(包括是否超时)。
  4. 如果验证码过期或者不正确,则返回相应的错误提示。
主要功能模块:
  • 验证码生成与存储
  • 验证码有效时间的检查
  • Redis 作为缓存存储验证码和其生成时间

三、项目依赖

首先,我们需要在 Spring Boot 项目中引入 Redis 的依赖,验证码需要通过 Redis 来进行存储,以支持分布式缓存和高效的读取。

代码语言:xml
AI代码解释
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

同时,我们还需要引入验证码生成的工具类库,常用的有 kaptcha 或者 captcha-generator 等:

代码语言:xml
AI代码解释
复制
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

四、Redis 配置

接下来,我们需要配置 Redis 连接信息。在 application.yml 中,添加如下配置:

代码语言:yaml
AI代码解释
复制
spring:
  redis:
    host: localhost
    port: 6379
    timeout: 6000ms
    jedis:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0

五、验证码生成与存储逻辑

1. 编写验证码生成服务

我们将使用 Kaptcha 来生成图片验证码。首先定义一个 CaptchaService 用于生成验证码:

代码语言:java
AI代码解释
复制
import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.util.Config;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.awt.image.BufferedImage;
import java.util.Properties;

@Service
public class CaptchaService {

    private Producer kaptchaProducer;

    @PostConstruct
    public void init() {
        Properties properties = new Properties();
        properties.setProperty("kaptcha.border", "no");
        properties.setProperty("kaptcha.textproducer.font.color", "black");
        properties.setProperty("kaptcha.textproducer.char.space", "5");
        Config config = new Config(properties);
        kaptchaProducer = config.getProducerImpl();
    }

    public String createCaptcha() {
        return kaptchaProducer.createText();
    }

    public BufferedImage createCaptchaImage(String captchaText) {
        return kaptchaProducer.createImage(captchaText);
    }
}
2. Redis 存储验证码与有效时间

当生成验证码后,我们将验证码及其生成时间存储到 Redis 中,设置一个过期时间(如5分钟),验证码生成时的时间戳也需要一并存储,以便后续验证。

代码语言:java
AI代码解释
复制
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class CaptchaStoreService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private final long CAPTCHA_EXPIRE_TIME = 5 * 60; // 5分钟

    public void saveCaptcha(String captchaId, String captchaText) {
        redisTemplate.opsForValue().set(captchaId, captchaText, CAPTCHA_EXPIRE_TIME, TimeUnit.SECONDS);
    }

    public String getCaptcha(String captchaId) {
        return redisTemplate.opsForValue().get(captchaId);
    }

    public boolean deleteCaptcha(String captchaId) {
        return redisTemplate.delete(captchaId);
    }
}

六、验证码验证逻辑

在用户提交验证码时,我们需要检查验证码是否存在、是否过期、是否正确。

代码语言:java
AI代码解释
复制
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CaptchaValidationService {

    @Autowired
    private CaptchaStoreService captchaStoreService;

    public boolean validateCaptcha(String captchaId, String captchaInput) {
        String storedCaptcha = captchaStoreService.getCaptcha(captchaId);

        if (storedCaptcha == null) {
            // 验证码不存在或已过期
            return false;
        }

        return storedCaptcha.equalsIgnoreCase(captchaInput);
    }
}

七、Controller 层实现

为了将上述逻辑整合到系统中,我们需要编写一个控制器来生成并验证验证码。

1. 生成验证码的接口
代码语言:java
AI代码解释
复制
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
public class CaptchaController {

    @Autowired
    private CaptchaService captchaService;

    @Autowired
    private CaptchaStoreService captchaStoreService;

    @GetMapping("/captcha/{captchaId}")
    public void getCaptcha(@PathVariable String captchaId, HttpServletResponse response) throws IOException {
        String captchaText = captchaService.createCaptcha();
        captchaStoreService.saveCaptcha(captchaId, captchaText);
        BufferedImage image = captchaService.createCaptchaImage(captchaText);
        response.setContentType("image/jpeg");
        ImageIO.write(image, "jpg", response.getOutputStream());
    }
}
2. 验证验证码的接口
代码语言:java
AI代码解释
复制
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LoginController {

    @Autowired
    private CaptchaValidationService captchaValidationService;

    @PostMapping("/login")
    public String login(@RequestParam String captchaId, @RequestParam String captchaInput) {
        boolean isCaptchaValid = captchaValidationService.validateCaptcha(captchaId, captchaInput);
        
        if (!isCaptchaValid) {
            return "验证码错误或已过期";
        }

        // 执行后续登录逻辑...
        return "登录成功";
    }
}

八、使用 Redis 实现验证码过期管理

Redis 提供了对键值的过期时间设置功能,在生成验证码时,我们将其存入 Redis 并设置一个过期时间。这种方法简洁且高效,特别适用于分布式系统。每次验证码生成时,Redis 会自动删除过期的验证码数据,保证不会有冗余信息存留。

在我们的代码中,我们通过 StringRedisTemplateopsForValue() 方法,将验证码存储到 Redis 并设定其存活时间。当用户提交验证码进行验证时,首先检查 Redis 中是否存在该验证码,若不存在则表明验证码已过期。

十、总结

通过本文的详细介绍,我们使用 Spring Boot 搭建了一个带有效时间的验证码登录系统。整个过程包括了验证码的生成、存储、有效时间的设定、验证等步骤。通过 Redis 的过期时间特性,轻松实现了验证码的有效期控制。这种方法适用于大多数应用场景,并且具有较高的安全性和可扩展性。在实际生产环境中,还可以根据业务需求对验证码的生成方式、存储策略、验证逻辑等做进一步优化。

总的来说,验证码的引入和有效时间控制是 Web 应用安全体系中的重要环节。通过合理的配置和实现,可以显著提升系统对暴力破解和恶意攻击的防御能力。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Springboot +redis+⾕歌开源Kaptcha实现图片验证码功能
用户7630333
2023/12/07
3860
Springboot +redis+⾕歌开源Kaptcha实现图片验证码功能
Springboot项目中kaptcha验证码的使用
知识浅谈
2024/01/02
2670
Springboot使用kaptcha验证码
chao超的搬运文章
2023/10/15
4090
分布式验证码登录方案
为了防止验证系统被暴力破解,很多系统都增加了验证码效验,比较常见的就是图片二维码,业内比较安全的是短信验证码,当然还有一些拼图验证码,加入人工智能的二维码等等,我们今天的主题就是前后端分离的图片二维码登录方案。
JAVA葵花宝典
2020/07/03
2.2K0
分布式验证码登录方案
生成图形验证码是如此简单
依赖 <!-- kaptcha验证码--> <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </dependency> 获取图形验证码 前端传入uuid,后端通过uuid作为redis缓存key import com.google.code.kaptcha.Constants; import com.google.c
用户8889406
2023/03/05
7500
Java 实战系列·Kaptcha 与数学公式验证码
Google 的 kaptcha 框架是一个高度可配置的实用验证码生成工具,官方地址:kaptcha github。
数媒派
2022/12/01
7880
Spring Boot 3 整合Hutool-captcha实现图形验证码
在整合技术框架的时候,想找一个图形验证码相关的框架,看到很多验证码不在更新了或者是在中央仓库下载不下来,还需要多引入依赖。后面看到了Hutool 图形验证码(Hutool-captcha)中对验证码的实现,提供了:线段干扰验证码、圆圈干扰验证码、扭曲干扰验证码以及自定义验证码。就此验证码在项目中的使用展开说明。
Harry技术
2025/01/12
9940
Spring Boot 3 整合Hutool-captcha实现图形验证码
kaptcha验证码插件的使用
CBeann
2023/12/25
2830
kaptcha验证码插件的使用
SpringBoot3整合Hutool-captcha实现图形验证码
如果你想像Spring-Boot一样引入Hutool,再由子模块决定用到哪些模块,你可以在父模块中加入:
Harry技术
2025/01/13
5160
SpringBoot3整合Hutool-captcha实现图形验证码
验证码这样做,瞬间高出一个逼格
拖动式验证就是根据图片显示,将指定的图形拖动到指定位置完成验证。而点触式验证码就是通过鼠标点击出示例中出现的图形完成验证。
Java宝典
2021/11/09
1.1K0
验证码这样做,瞬间高出一个逼格
springbooot使用google验证码
由于需要做一个前后端分离的项目,想着使用google验证码,由于年龄大了,这些知识啊,用完就忘,在这里记录一下。
魚迹
2023/05/06
5520
springbooot使用google验证码
登录验证码demo-java
在一些类似于管理系统的项目中,我们在登录时经常会用到图片验证码。这里把我自己写的一个小系统(后台是java语言)的验证码部分摘出来。 总体思路是后端有一个生成验证码图片的接口,把验证码图片写入浏览器,前端页面在img标签里的src属性里填写后端生成验证码图片的接口地址即可。 1、java部分-CaptchaController.java 我这里是把后端生成的验证码生成图片返回给浏览器时,同时存入到了数据库中,前端登录时,后端根据前端输入的验证码和数据库中的验证码作对比,来判断是否可以登录。 package
用户1174387
2018/01/17
3.5K0
登录验证码demo-java
Spring Security---验证码详解
验证码实际上和谜语有点像,分为谜面和谜底。谜面通常是图片,谜底通常为文字。谜面用于展现,谜底用于校验。
大忽悠爱学习
2021/12/07
1.2K0
Spring Security---验证码详解
验证码的花式玩法
TienChin 项目出视频啦~Spring Boot+Vue3,和松哥一起做一个完成率超 90% 的项目,戳戳戳这里-->TienChin 项目配套视频来啦。 ---- 在 vhr 项目中,松哥也跟大家讲了验证码的用法,不过那个里边的验证码是我们自己写的,其实功能也还算完整,够用。不过现在各个网站的验证码玩法花样越来越多,加上最近在搞的 TienChin 项目用的验证码是一个老牌开源库 kaptcha,所以松哥决定还是花点时间,跟大家聊聊 kaptcha 的用法,毕竟这个已经有 16 年历史的玩意还在有人
江南一点雨
2022/05/12
5270
验证码的花式玩法
Kaptcha图片验证码工具
图片验证码自从诞生以来从未被抛弃,依然发出属于它所应有的光。验证码经常验证如下一些场景。
BUG弄潮儿
2020/06/12
4.2K0
Kaptcha图片验证码工具
SpringBoot|Spring-Data-Redis 验证码短信存储服务
接着上一篇继续说,上一篇主要的还是连接邮箱和发信测试,这次主要就是对于接口制作和测试了
程序员Jony
2023/01/03
1.5K0
SpringBoot|Spring-Data-Redis 验证码短信存储服务
图像验证码
无意之中发现一个好玩的东西,那就是生成验证码图片,感觉还挺好玩的。意外看到 kaptcha
是小张啊喂
2021/08/09
1.4K0
java 实现登录验证码 (kaptcha 验证码组件)
而 kaptcha工作的原理,是调用 com.google.code.kaptcha.servlet.KaptchaServlet,生成一个图片。同时将生成的验证码字符串放到 HttpSession中,直接从session中获取这张验证码图片,而不会占用实际内存。
Krry
2019/03/23
8.7K0
SpringBoot实现验证码--kaptcha
目标:SpringBoot实现验证码--kaptcha 工具:IDEA--2020.1 学习目标:SpringBoot实现验证码--kaptcha 本次学习的工程比较简单,不放置工程!
背雷管的小青年
2020/06/09
1.4K0
Shiro集成验证码--Java学习网
在做用户登录功能时,很多时候都需要验证码支持,验证码的目的是为了防止机器人模拟真实用户登录而恶意访问,如暴力破解用户密码/恶意评论等。目前也有一些验证码比较简单,通过一些OCR工具就可以解析出来;另外还有一些验证码比较复杂(一般通过如扭曲、加线条/噪点等干扰)防止OCR工具识别;但是在中国就是人多,机器干不了的可以交给人来完成,所以在中国就有很多打码平台,人工识别验证码;因此即使比较复杂的如填字、算数等类型的验证码还是能识别的。所以验证码也不是绝对可靠的,目前比较可靠还是手机验证码,但是对于用户来说相对于验证码还是比较麻烦的。
用户1289394
2021/01/20
5710
Shiro集成验证码--Java学习网
相关推荐
Springboot +redis+⾕歌开源Kaptcha实现图片验证码功能
更多 >
交个朋友
加入腾讯云官网粉丝站
双11活动抢先看 更有社群专属礼券掉落
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档