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

防刷发送短信验证码接口的五种简单好用方法绝对够用

防刷发送短信验证码接口的五种简单好用方法,绝对够用

  1. 前端增加图形验证码,点击发送按钮后增加60s倒计时,60s后才可以再次点击

  2. 后端对接口次数校验,60s内同一电话号码只能发送一次

    // 生成基于电话号码的重试锁定键
    String repeatLock = StringUtils.join("send_sms:", mobile);// 使用 Redis 的 setIfAbsent 进行原子性操作,尝试设置键值对,如果键已存在则返回 false
    if (!redisTemplate.opsForValue().setIfAbsent(repeatLock, "locked", 60, TimeUnit.SECONDS)) {// 键已存在,表示1分钟内已经发送过短信LOGGER.error("60s内不能重复调用发送短信功能: {}", mobile);throw new RuntimeException("调用发送验证码过于频繁,请稍后再试!");
    }
    
  3. 后端增加每天次数校验,每个电话号码每天只能发送50次

     private static final int MAX_DAILY_SMS = 50; // 每日最大短信发送数量// 获取当前日期作为短信发送统计的键
    String dailySmsKey = getDailySmsCountKey(LocalDate.now(),mobile);// 检查每日短信发送数量是否超出限制
    long currentDaySmsCount = redisTemplate.opsForValue().increment(dailySmsKey,1);//设置过期时间为当天23:59:59
    LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.of(23, 59, 59));
    long secondsUntilMidnight = ChronoUnit.SECONDS.between(LocalDateTime.now(), todayEnd);
    redisTemplate.expire(dailySmsKey, secondsUntilMidnight, TimeUnit.SECONDS);
    if (currentDaySmsCount > MAX_DAILY_SMS) {LOGGER.error("今日短信发送已达上限,无法再发送给 {}", mobile);throw new RuntimeException("当日短信发送已达上限,无法再发送,请明日再试!");
    }private String getDailySmsCountKey(LocalDate date,String mobile) {return "sms_daily_count:" +mobile + date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));}
    
  4. 对每日超过50次的ip记录下来,也可以加入黑名单,下次判断请求ip为黑名单中的ip则直接返回失败

  5. 前后端增加一个对称加密的校验码

    准备:密钥 1234abcd;约定明文中必须包含指定字符串miyao1234

    1.前端调用发送短信接口前,通过密钥(1234abcd)与加密算法,将miyao1234+(16位英文字母与数字字符串) 例如miyao1234wgly1noKSXg47Mn6 进行加密

    生成校验码 vBOLxJj3wl1IyJNUcXOPvaeXvgLZK0b4f3D4J6k9DvE=

    2.前端调用发送短信接口时,将校验码传递给后端

    3.后端接收到后对校验码进行解密,如果解密失败,提示失败

    4.如果解密后不包含约定字符串miyao1234 ,提示失败

    5.如果解密后包含约定字符串miyao1234,则通过校验,此时注意⚠️,需要将此校验码存入redis,下次如果有相同校验码 则提示重复

      /*** 解密后的验证码必须包含此值*/public static final String ENCRYPT_KEY_MAIN_WORD = "miyao1234";//密钥1234abcdpublic static final String encryptKey = "1234abcd";Validate.notBlank(keyDecrypt,"发送短信时,校验码不能为空");
    //进行解密
    String decrypt = this.decrypt(keyDecrypt);
    LOGGER.error("发送验证码解密后的校验码"+decrypt);
    if(StringUtils.isEmpty(decrypt) || !decrypt.contains(ENCRYPT_KEY_MAIN_WORD)){throw new RuntimeException("发送验证码校验失败");
    }
    //设置过期时间为当天23:59:59
    // 每个校验码每天只能重复使用一次
    String repeatLock = StringUtils.join("decrypt_send_sms:", decrypt);
    LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.of(23, 59, 59));
    long secondsUntilMidnight = ChronoUnit.SECONDS.between(LocalDateTime.now(), todayEnd);
    // 使用 Redis 的 setIfAbsent 进行原子性操作,尝试设置键值对,如果键已存在则返回 false
    if (!redisTemplate.opsForValue().setIfAbsent(repeatLock, "locked", secondsUntilMidnight, TimeUnit.SECONDS)) {// 键已存在,表示校验码重复throw new RuntimeException("校验码重复!");
    }public String decrypt(String decrypt) {if (StringUtils.isBlank(decrypt)) {return decrypt;}return Aes128Utils.decrypt(decrypt, encryptKey, Aes128Utils.EncodeType.CBC, Aes128Utils.Padding.PKCS_7_PADDING);}

相关文章:

防刷发送短信验证码接口的五种简单好用方法绝对够用

防刷发送短信验证码接口的五种简单好用方法,绝对够用 前端增加图形验证码,点击发送按钮后增加60s倒计时,60s后才可以再次点击 后端对接口次数校验,60s内同一电话号码只能发送一次 // 生成基于电话号码的重试锁定键 String repeat…...

ubuntu中idea创建spark项目步骤

1.前置条件 ubuntu中已经安装idea,jdk,scala,spark 2.打开idea,新建,选择Maven项目 3.在IDEA中,File-Setting-Plugin,下载Scala插件 4.File-project structure,导入插件 4.1在全局库中,选择导入刚才的sca…...

回文链表(快慢指针解法之在推进过程中反转)

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言​📝抱怨深处黑暗,不如提灯前行…...

深度剖析:为什么 Spring 和 IDEA 都不推荐使用 @Autowired 注解

目录 依赖注入简介 Autowired 注解的优缺点 Spring 和 IDEA 不推荐使用 Autowired 的原因 构造器注入的优势 Autowired 注解的局限性 可读性和可测试性的问题 推荐的替代方案 构造器注入 Setter 注入 Java Config Bean 注解 项目示例:Autowired vs 构造器…...

【接口自动化_05课_Pytest接口自动化简单封装与Logging应用】

一、关键字驱动--设计框架的常用的思路 封装的作用:在编程中,封装一个方法(函数)主要有以下几个作用:1. **代码重用**:通过封装重复使用的代码到一个方法中,你可以在多个地方调用这个方法而不是…...

信息学奥赛初赛天天练-14-阅读程序-字符数组、唯一分解定理应用

更多资源请关注纽扣编程微信公众号 1 2019 CSP-J 阅读程序1 (程序输入不超过数组或字符串定义的范围;判断题正确填√,错误填;除特殊说明外,判断题1.5分,选择题3分,共计40分) 1 输入的字符串只能由小写字母或大写字母组…...

K210 数字识别 笔记

一、烧写固件 连接k210开发板,点开烧录固件工具,选中固件,并下载 二、模型训练 网站:MaixHub 1、上传文件 2、开始标记数据 添加9个标签,命名为1~9,按键盘w开始标记,键盘D可以下一张图片&…...

人脸检测--FaceNet(四)

FaceNet 是一个由 Google 研究团队开发的人脸识别系统,它基于深度学习技术,可以实现高精度的人脸识别、验证和聚类任务。FaceNet 通过学习直接从图像像素到人脸嵌入的映射,使得它在各种人脸识别任务中表现出色。下面是对 FaceNet 的详细介绍&…...

Android性能优化方案

1.启动优化: application中不要做大量耗时操作,如果必须的话,建议异步做耗时操作2.布局优化:使用合理的控件选择,少嵌套。(合理使用include,merge,viewStub等使用)3.apk优化(资源文件优化&#…...

视频监控平台AS-V1000 的场景管理,一键查看多画面视频的场景配置、调用、管理(一键浏览多路视频)

目录 一、场景管理的定义 二、场景管理的功能和特点 1、功能 (1)场景配置 (2)实时监控 (3)权限管理 2、特点 三、AS-V1000的场景配置和调用 1、场景配置 (1)实时视频预览 …...

微服务架构五大设计模式详解,助你领跑行业

微服务架构设计模式详解(5种主流模式) 微服务架构 微服务,一种革命性的架构模式,主张将大型应用分解为若干小服务,通过轻量级通信机制互联。每个服务专注特定业务,具备独立部署能力,轻松融入生产环境,为系…...

【problem】解决EasyExcel导出日期数据显示为#####问题

前言 在使用EasyExcel进行数据导出时,你可能遇到日期或其他数据在Excel中显示为“#######”的情况,这通常是因为列宽不足以展示单元格内的全部内容。本文将指导你如何通过简单的步骤解决这一问题,并确保导出的Excel文件自动调整列宽或直接指…...

Pytest用例自定义 - 重复、并行、串行

简介:面对快速迭代和持续交付的需求,提高测试效率变得至关重要。并行测试因其显著的时间节省优势而备受青睐。然而,并非所有测试都适合并行执行。在某些情况下,串行执行是必要的,以确保测试的正确性和稳定性。本文将探…...

前端项目上线

目录 1项目打包 2本地服务器部署 2.1具体操作步骤 2.2解决刷新 404 问题 2.3请求无法发送问题 3nginx 服务器部署 3.2nginx 配置代理练习 安装nginx nginx部署启动项目 3.3nginx 部署前端项目 4云服务器部署 本地资源上传 配置服务器与nginx 1项目打包 ●我…...

redis基本数据结构与应用

文章目录 概要String结构Hash结构List结构Set结构Zset结构bitmap位图类型geo地理位置类型其他常用命令 概要 redis常用的5种不同数据结构类型之间的映射如下: 结构类型结构存储的值结构的读写能力STRING可以是字符串、整数或者浮点数key-value形式;对整…...

Python pands使用引擎实现excel条件格式

截至我的知识更新日期(2023年),Pandas 库本身并不直接支持Excel条件格式。Pandas 是一个强大的Python数据分析库,它主要用于数据分析和操作,而不是用于创建或编辑Excel文件的格式。 然而,你可以使用 openp…...

基于 vuestic-ui 实战教程 - 登录篇

1. 简介 登录做为一个系统的门面,也是阻挡外界的一道防线,那在vuestic-ui中如何做登录功能呢。在这里就之间沿用初始版本的Login页面,作为一个演示模板,后续需要改进的读者可以在此篇文章的基础上修改。 2. 登录接口相关api 与 t…...

SAPUI5基础知识2 - 手动创建一个SAPUI5的项目

1. 前言 在本篇文章中,我们将手动一步一步建立出第一个SAPUI5的 ‘Hello World!’ 项目。 2. 步骤详解 2.1 在BAS中建立Dev Space 进入SAP Business Application Studio的Dev Space Manger,选择创建Dev Space。 勾选HTML5 Application Template插件…...

设计模式--访问者模式

访问者模式是一种行为设计模式,它用于将算法与对象结构分离,使得算法可以独立于使用它的数据结构而变化。这种模式在许多应用场景中非常有用,例如在实现图形算法、数据结构遍历、文件格式转换以及代码分析时。 应用场景 图形算法&#xff1…...

onnx模型转换到rknn脚本

from rknn.api import RKNN ONNX_MODEL ./onnx_models/yolov5s_rm_transpose.onnx # platform"rk1808" platform "rv1109" RKNN_MODEL yolov5s_relu_{}_out_opt.rknn.format(platform) if __name__ __main__: add_perm False # 如果设置成True,则将模…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

论文阅读:Matting by Generation

今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...