当前位置: 首页 > article >正文

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

文章目录

    • 依赖配置
    • 开启 QQ 邮箱 SMTP 服务
    • 配置文件
    • 代码实现
      • 验证码服务
      • 邮件服务
      • 接口实现
      • 执行流程

依赖配置

<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. 点击左上角的齿轮按钮,进入设置页面,见下图:
    QQMailHeader4. 在设置中找到“第三方服务”,激活 IMAP/SMTP(默认为禁用),并生成独立的 SMTP 授权码。 MailBoxSetting

配置文件

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 缓存验证码并实现验证码的校验功能:

@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);  
    }  
}

邮件服务

@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);  
    }
}

接口实现

@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. 系统校验验证码,验证成功则注册,失败则返回错误信息。

http://www.kler.cn/a/567015.html

相关文章:

  • 华为hcia——Datacom实验指南——STP工作基本原理及STP/RSTP基本功能配置
  • PHP对接微信支付v3版本
  • 从0开始的IMX6ULL学习篇——裸机篇之外设资源分析
  • mysql系列10—mysql锁
  • 如何使用 preg_replace 处理复杂字符串替换
  • 测试向丨多模态大模型能做宠物身份识别吗?
  • Express + MongoDB 实现 VOD 视频点播
  • QT:Echart-折线图
  • JeeWMS cgReportController.do 多个参数SQL注入漏洞(CVE-2024-57760)
  • Jeecg-Boot 开放接口开发实战:在 Jeecg-Boot 的jeecg-system-biz中添加一个controller 实现免鉴权数据接口
  • AcWing 农夫约翰的奶酪块
  • DeepSeek引爆AI浪潮:B站如何成为科技普惠的“新课堂”?
  • Linux Mem -- 关于AArch64 MTE功能的疑问
  • 大数据与金融科技:革新金融行业的动力引擎
  • CSS Selectors
  • unity学习56:旧版legacy和新版TMP文本输入框 InputField学习
  • STM32G431RBT6——(1)芯片命名规则
  • 每天一个Flutter开发小项目 (8) : 掌握Flutter网络请求 - 构建每日名言应用
  • Kafka重复消费问题和解决方式
  • Redis大key