spring boot3登录开发-邮件验证码接口实现

06-15 876阅读

 spring boot3登录开发-邮件验证码接口实现

⛰️个人主页:     蒾酒

🔥系列专栏:《spring boot实战》


目录

写在前面

上文衔接

接口设计与实现 

1.接口分析

2.实现思路

3.代码实现

1.定义验证码短信HTML模板枚举类

2.定义验证码业务接口

3. 验证码业务接口实现

4.控制层代码

4.测试

写在最后


最近发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。

    点击跳转到学习网站

spring boot3登录开发-邮件验证码接口实现

写在前面

本文介绍了springboot开发后端服务中,邮件验证码接口功能的设计与实现,坚持看完相信对你有帮助。

同时欢迎订阅springboot系列专栏,持续分享spring boot的使用经验。

上文衔接

实现发送验证码邮件接口的前提是项目中已经整合好了邮件服务。上篇文章介绍了springboot整合QQ邮箱SMTP服务:spring boot3整合邮件服务实现邮件发送功能_spring-boot-starter-mail springboot3-CSDN博客spring boot3登录开发-邮件验证码接口实现https://blog.csdn.net/qq_62262918/article/details/139244604

接口设计与实现 

1.接口分析

关键点:

  1. 邮件验证码60s发送间隔
  2. 连发多次封禁24H
  3. 5分钟有效期

2.实现思路

接口接收一个邮箱号参数,先去redis查询该邮箱是否有未过期的验证码,如果有先判断发送次数,超过5次,先修改过期时间为24H,再抛发送次数过多异常,少于五次,就再判断发送频率,距离上次发送间隔少于60s,就抛出发送频繁异常,  如果没有未过期的验证码,代表这是第一次发送就直接生成验证码发送短信,接着redis存入一个哈希,key通过手机号生成,value就是,三个键值对,验证码,上次发送时间戳,发送次数(初始为1),默认过期时间5分钟。

  1. 接收手机号参数。
  2. 查询 Redis 中该手机号是否有未过期的验证码。
  3. 如果有未过期的验证码:
    1. 判断发送次数是否超过5次,如果超过5次,修改过期时间为24小时并抛出发送次数过多异常。
    2. 如果发送次数未超过5次,再判断距离上次发送时间间隔是否少于60秒,如果少于60秒,抛出发送频繁异常。
  4. 如果没有未过期的验证码,代表第一次发送:
    1. 生成验证码并发送短信。
    2. 将验证码信息存入 Redis,包括验证码、上次发送时间戳和发送次数(初始为1),设置过期时间为5分钟。

注意事项:

考虑到验证码本身的敏感性,虽然存入Redis是临时的,但考虑安全建议对验证码内容进行加密存储,增强数据的安全性。

考虑对接口调用方进行身份验证,确保只有合法的客户端可以请求发送验证码。

整合redis:

Spring Boot3整合Redis_springboot3整合redis-CSDN博客文章浏览阅读6.6k次,点赞103次,收藏111次。⛰️个人主页: 蒾酒🔥系列专栏:《spring boot实战》目录前置条件1.导依赖2.配置连接信息以及连接池参数3.配置序列化方式4.编写测试已经初始化好一个spring boot项目且版本为3X,项目可正常启动。作者版本为3.2.2初始化教程:新版idea(2023)创建spring boot3项目-CSDN博客https://blog.csdn.net/qq_62262918/article/details/135785412?spm=1001.2014.3001.5501pom.xml:_springboot3整合redisspring boot3登录开发-邮件验证码接口实现https://blog.csdn.net/qq_62262918/article/details/136067550?spm=1001.2014.3001.5501

3.代码实现

1.定义验证码短信HTML模板枚举类

在实际业务中可能需要发送各种类型的邮件通知,将不同类型的邮件定义为模板维护在枚举中也是种不错选择。

import lombok.Getter;
import java.util.Locale;
/**
 * @author mijiupro
 */
@Getter
public enum EmailTemplateEnum {
    // 验证码邮件
    VERIFICATION_CODE_EMAIL_HTML("用户你好,你的验证码是:

%s

","登录验证"), // 用户被封禁邮件通知 USER_BANNED_EMAIL("用户你好,你已经被管理员封禁,封禁原因:%s", "封禁通知"), ; private final String template; private final String subject; EmailTemplateEnum(String template, String subject) { this.template = template; this.subject = subject; } public String value() { return this.template; } /** * 模板参数填充 * @param args 参数集 * @return 填充后的字符串 */ public String set(Object... args) { return String.format(Locale.ROOT, this.template, args); } }

2.定义验证码业务接口

public interface CaptchaService {
    /**
     * 获取邮箱验证码
     * @param email 邮箱
     */
    void getMailCaptcha(String email);
}

3. 验证码业务接口实现

import com.mijiu.commom.enumerate.EmailTemplateEnum;
import com.mijiu.commom.exception.GeneralBusinessException;
import com.mijiu.api.email.EmailApi;
import com.mijiu.api.sms.SmsApi;
import com.mijiu.service.CaptchaService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
 * @author mijiupro
 */
@Service
@Slf4j
public class CaptchaServiceImpl implements CaptchaService {
    private final StringRedisTemplate stringRedisTemplate;
    private final SmsApi smsUtil;
    private final EmailApi emailUtil;
    public CaptchaServiceImpl(StringRedisTemplate stringRedisTemplate, SmsApi smsUtil, EmailApi emailUtil) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.smsUtil = smsUtil;
        this.emailUtil = emailUtil;
    }
    
    @Override
    public void getMailCaptcha(String email) {
        getCaptcha("login:email:captcha:" + email);
    }
    
    private void getCaptcha(String hashKey) {
        BoundHashOperations hashOps = stringRedisTemplate.boundHashOps(hashKey);
        // 初始检查
        String lastSendTimestamp = hashOps.get("lastSendTimestamp");
        String sendCount = hashOps.get("sendCount");
        String captcha = hashOps.get("captcha");
        // 判断发送次数是否超过限制
        if (StringUtils.isNotBlank(sendCount) && Integer.parseInt(sendCount) >= 5) {
            hashOps.expire(24, TimeUnit.HOURS); // 重新设置过期时间为24H
            throw new GeneralBusinessException("发送次数过多,请24H后再试");
        }
        // 判断发送频率是否过高
        if (StringUtils.isNotBlank(lastSendTimestamp)) {
            long lastSendTime = Long.parseLong(lastSendTimestamp);
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - lastSendTime;
            long interval = 60 * 1000; // 60秒
            if (elapsedTime  

4.控制层代码

import com.mijiu.service.CaptchaService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author mijiupro
 */
@RestController
@RequestMapping("/captcha")
@Tag(name = "验证码接口", description = "验证码接口相关操作")
public class CaptchaController {
    private final CaptchaService captchaService;
    public CaptchaController(CaptchaService captchaService) {
        this.captchaService = captchaService;
    }
   
    @GetMapping("/mail-captcha/{email}")
    @Operation(summary = "获取邮箱验证码")
    public void getEmailCaptcha(@PathVariable String email) {
        captchaService.getMailCaptcha(email);
    }
   
}

到这里接口已经实现。

4.测试

用swagger3进行测试:

Spring Boot3整合knife4j(swagger3)_springboot3 knife4j-CSDN博客spring boot3登录开发-邮件验证码接口实现

发送请求

spring boot3登录开发-邮件验证码接口实现 这是redis已经缓存了验证码信息

spring boot3登录开发-邮件验证码接口实现

也收到了验证码邮件

spring boot3登录开发-邮件验证码接口实现

写在最后

 邮件验证码接口功能的设计与实现到这里就结束了,任何问题评论区或私信讨论,欢迎指正。

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]