Spring Boot 3.x 基于 Redis 实现邮箱验证码认证

文章目录

依赖配置

xml 复制代码
<dependencies> 
    <!-- Spring Boot Starter Web --> 
    <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
    
    <!-- Redis 集成依赖  -->  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-data-redis</artifactId>  
        <version>3.4.2</version>  
    </dependency>  
    
    <dependency>  
        <groupId>org.apache.commons</groupId>  
        <artifactId>commons-pool2</artifactId>  
        <version>2.11.1</version>  
    </dependency>  
    
    <dependency>  
        <groupId>io.lettuce</groupId>  
        <artifactId>lettuce-core</artifactId>  
        <version>6.3.2.RELEASE</version>  
    </dependency>
    
    <!-- 邮件发送支持 --> 
    <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-mail</artifactId> 
    </dependency> 
    
    <!-- 验证码生成工具 --> 
    <dependency> 
        <groupId>commons-lang</groupId> 
        <artifactId>commons-lang</artifactId> 
        <version>2.6</version> 
    </dependency>
</dependencies>

开启 QQ 邮箱 SMTP 服务

  1. 打开浏览器,登录到 QQ 邮箱。
  2. 点击左上角的齿轮按钮,进入设置页面,见下图:
    4. 在设置中找到"第三方服务",激活 IMAP/SMTP(默认为禁用),并生成独立的 SMTP 授权码。

配置文件

yaml 复制代码
spring:  
  data:  
    redis:  
      host: your_redis_host
      port: your_redis_port # 通常为6379
      password: your_redis_password
      lettuce:  
        pool:  
          max-active: 8 # 最大连接数  
          max-idle: 8 # 最大空闲连接数  
          min-idle: 0 # 最小空闲连接数  
          max-wait: 100 # 连接等待时间  
  mail:  
    host: smtp.qq.com  
    port: 465  
    username: your_qq_account@qq.com
    password: 111 # 输入 QQ 邮箱的授权码
    properties:  
      mail:  
        smtp:  
          ssl:  
            enable: true  # QQ 邮箱需要开启 SSL
          auth: true

代码实现

验证码服务

使用 Redis 缓存验证码并实现验证码的校验功能:

java 复制代码
@Service  
public class CaptchaService {  
  
    @Autowired  
    private StringRedisTemplate redisTemplate;  
  
    /**  
     * 生成验证码  
     * @param email 目标邮箱  
     * @return 生成的验证码  
     */  
    public String generateCaptcha(String email) { 
        // 生成验证码  
        String code = RandomStringUtils.randomNumeric(6);  
        redisTemplate.opsForValue().set(  
                "CAPTCHA:" + email,  
                code,  
                Duration.ofMinutes(5)  // 验证码有效期为5分钟  
        );  
        return code;  
    }  
  
    /**  
     * 验证码校验  
     * @param email 邮箱  
     * @param code 验证码  
     * @return 是否验证通过  
     */  
    public boolean validateCaptcha(String email, String code) {  
        String captcha = redisTemplate.opsForValue().get("CAPTCHA:" + email);  
        return captcha != null && captcha.equals(code);  
    }  
}

邮件服务

java 复制代码
@Service  
public class EmailService {  
  
    @Autowired  
    private JavaMailSender mailSender;  
  
    /**  
     * 发送验证码邮件  
     * @param email 收件人邮箱  
     * @param authCode 验证码  
     */  
    public void sendCaptchaEmail(String email, String authCode) {  
        SimpleMailMessage message = new SimpleMailMessage();  
        message.setFrom("your_qq_account@qq.com");  
        message.setTo(email);  
        message.setSubject("验证码");  
        message.setText("您的验证码是:" + authCode + ",有效期为5分钟");  
        mailSender.send(message);  
    }
}

接口实现

java 复制代码
@RestController  
public class AuthController {  
  
    @Autowired  
    private UserService userService;  
  
    @Autowired  
    private CaptchaService captchaService;  
  
    @Autowired  
    private EmailService emailService;  
  
    /**  
     * 注册接口  
     * @param userDTO 用户信息  
     * @param captcha 验证码  
     * @return 注册结果  
     */  
    @PostMapping("/register")  
    public Result register(@RequestBody UserDTO userDTO, @RequestParam String captcha) {  
        if (!captchaService.validateCaptcha(userDTO.getEmail(), captcha)) {  
            return Result.error("验证码错误");  
        }  
        userService.register(userDTO);  
        return Result.success();  
    }  
  
    /**  
     * 登录接口  
     * @param userDTO 用户信息  
     * @return 登录结果  
     */  
    @PostMapping("/login")  
    public Result login(@RequestBody UserDTO userDTO) {  
        User user = userService.login(userDTO);  
        if (user == null) {  
            return Result.error("用户不存在");  
        }  
        // 登录成功,生成 JWT 令牌  
        Map<String, Object> claims = new HashMap<>();  
        claims.put("userId", user.getId());  
        String token = JwtUtils.createJWT("secretKey", 60000, claims);  
        UserVO userVO = new UserVO();  
        BeanUtils.copyProperties(user, userVO);  
        LoginResponse loginResponse = new LoginResponse(userVO, token);  
        return Result.success(loginResponse);  
    }  
  
    /**  
     * 发送验证码接口  
     * @param email 邮箱地址  
     * @return 发送结果  
     */  
    @PostMapping("/send-code")  
    public Result sendCode(@RequestParam String email) throws MessagingException {  
        // 校验邮箱格式
        if (!RegexUtils.isEmailValid(email)) {  
            return Result.error("邮箱格式非法");  
        }  
        String code = captchaService.generateCaptcha(email);  
        emailService.sendCaptchaEmail(email, code);  
        return Result.success();  
    }  
}

执行流程

  1. 用户输入邮箱,调用 /send-code 接口获取验证码。
  2. 用户填写验证码并调用 /register 接口进行注册。
  3. 系统校验验证码,验证成功则注册,失败则返回错误信息。
相关推荐
uzong2 小时前
技术故障复盘模版
后端
GetcharZp2 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程3 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研3 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi3 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
一只爱撸猫的程序猿4 小时前
使用Spring AI配合MCP(Model Context Protocol)构建一个"智能代码审查助手"
spring boot·aigc·ai编程
甄超锋4 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
阿华的代码王国4 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy4 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
鼠鼠我捏,要死了捏5 小时前
生产环境Redis缓存穿透与雪崩防护性能优化实战指南
redis·cache