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

短信验证码发送实现(详细教程)

短信验证码

  • 接口防刷
  • 强检验以及缓存验证码
  • 阿里云短信服务操作步骤
  • 验证码发送实现

好久没发文啦!最近也是在工作中遇到我自认为需要记录笔记的需求,本人只求日后回顾有迹可寻,不喜勿喷!
废话不多说,直接上代码!

@ResponseBody
    @GetMapping("/sms/sendcode")
    public R sendCode(@RequestParam("phone") String phone) {
        //从Redis中获取要发送验证码的手机号对应的value
        String redisCode = redisTemplate.opsForValue().get(AuthConstants.SMS_CODE_CACHE_PREFIX + phone);
        if (!StringUtils.isEmpty(redisCode)) {
        //redisCode不为空,说明redis中是有该手机号的code缓存的
        //这个分隔是保存code码的格式(保存格式在下面的代码片段)
            long l = Long.parseLong(redisCode.split("_")[1]);
            if (System.currentTimeMillis() - l < 60000) {
            //如果当前时间与code缓存的时间差小于1分钟的话,是不允许再次发送验证码的
                return R.error(BizCode.SMS_CODE_EXCRPTION.getCode(), BizCode.SMS_CODE_EXCRPTION.getMsg());
            }
        }
        //redisCode不为空,该手机号是第一次调验证码发送接口
        //强检验验证码
        String code = UUID.randomUUID().toString().substring(0, 5);
        String s = code + "_" + System.currentTimeMillis();
        //缓存验证码
        redisTemplate.opsForValue().set(AuthConstants.SMS_CODE_CACHE_PREFIX + phone, s, 5, TimeUnit.MINUTES);
        //远程调用发送验证码服务
        log.info("------开始发送验证码------");
        R r = thirdPartyFeignService.sendCode(phone, code);
        if (r.getCode() == 200) {
            log.info("-----发送验证码成功------");
        }
        return R.ok();
    }

接口防刷

短信验证码一般做出来就是要加入防刷逻辑的,防止有些不怀好意的人对接口进行恶意调用,导致系统崩溃,对系统的性能和CPU负载都会有一定影响的,可能会导致之后页面请求后端数据时卡顿或者相应速度会很慢,影响用户的体验感。那接口防刷怎么做呢?我刚接触的时候觉得很复杂,熟悉之后发现逻辑上还是很简单的(校验位需要多种方式结合,用Redis存储)。

看出来了吧?实际上就是加了个时间的校验,这也是最简单的一种防刷方案。

强检验以及缓存验证码

利用UUID的随机性,再截取其中几位,通过“_”和系统时间进行拼接成redis中的value,缓存时间为5分钟,也就是该验证码5分钟内有效。

阿里云短信服务操作步骤

//TODO
日后有空更新!抱拳啦🙏🙏!

验证码发送实现

集成阿里云的短信验证码发送API模板,可以去阿里云官网的短信服务文档看看,还是很好理解的。

@ConfigurationProperties(prefix = "spring.cloud.alicloud.sms")
@Data
@Component
public class SmsComponent {

    private String host;
    private String path;
    private String mobile;
    private String appcode;

    public void sendCode(String phone,String code) {
        String method = "GET";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("mobile", phone);
        querys.put("content", "【智能云】您的验证码是"+code+"。如非本人操作,请忽略本短信");
        //JDK 1.8示例代码请在这里下载:  http://code.fegine.com/Tools.zip
        try {
            HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
            //System.out.println(response.toString());如不输出json, 请打开这行代码,打印调试头部状态码。
            //状态码: 200 正常;400 URL无效;401 appCode错误; 403 次数用完; 500 API网管错误
            //获取response的body
            System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

@ConfigurationProperties(prefix = “spring.cloud.alicloud.sms”)

@ConfigurationProperties是Spring Boot提供的一个注解,用于将外部配置属性绑定到Java对象上。通过使用这个注解,开发者可以将配置文件(如application.properties或application.yml)中的属性值自动映射到Java类的字段上,从而实现配置的集中管理和类型安全。

spring:
  cloud:
    alicloud:
      sms:
        host: 申请的短信host地址
        path: 短信验证码的接口路径(发送验证码接口所在的controller请求路径)
        appcode: 申请的APPCODE

以上配置对应的就是那几个变量值。

@ConfigurationProperties的作用

  • 配置绑定:将配置文件中的属性值绑定到Java类的字段上,实现配置的自动映射。
  • 类型安全:提供类型安全的配置绑定,避免类型转换错误。
  • 复杂配置:支持复杂配置结构的绑定,如嵌套对象、集合、Map等。
  • 配置校验:结合@Valid注解,实现配置属性的校验。

然后Postman完成自测,你会发现短信验证码的功能就实现啦!(阿里云短信服务可能需要付一点点的费用哦!)


http://www.kler.cn/news/367322.html

相关文章:

  • GCC 简介
  • API接口开放与安全管控 - 原理与实践
  • 从零学习大模型(五)-----提示学习(Prompt Engineering)
  • 如何预防数据打架?数据仓库如何保持指标数据一致性开发指南(持续更新)
  • 力扣刷题(sql)--零散知识点(1)
  • 【云原生网关】Higress 从部署到使用详解
  • bug记录, 构造与赋值???zzg::list<int> l; l = { 1, 2, 3 };为什么没写对应的赋值函数却可以跑?
  • Rust中的Send和Sync特征:确保并发安全
  • STM32硬件平台
  • Android——事件冲突处理
  • 时间序列预测(九)——门控循环单元网络(GRU)
  • HTTP快速入门
  • 实验04while(简单循环)---7-3 正负数个数
  • 985研一,转嵌入式好还是后端开发好?
  • 从React Hooks看React的本质
  • TensorFlow面试整理-如何处理 TensorFlow 中的梯度消失或爆炸问题?
  • 秋叶启动器下,如何升级ComfyUI的pytorch版本到2.5
  • ArrayList和linkedList的区别
  • 《虚拟现实的边界:探索虚拟世界的未来可能》
  • 项目部署 —— 前端、后端
  • 哪个品牌的骨传导耳机适合骑行?五款骑行爱好者都在推的运动耳机
  • 【C++刷题】力扣-#495-提莫攻击
  • ts:对象数组的简单使用
  • ArcGIS003:ArcMap常用操作0-50例动图演示
  • ubuntu18.04中如何设置桥接模式和静态ip
  • 深入图像处理:使用Pillow库的实用指南