背景:短信验证码接口被不法分子用来做灰产(短信邮箱轰炸机)

如何避免⾃⼰的⽹站成为”⾁鸡“或者被刷?

  • 增加图形验证码(开发⼈员)
  • 单IP请求次数限制(开发⼈员)

防刷之图形验证码(⾕歌kaptcha)

<dependency><groupId>com.baomidou</groupId><artifactId>kaptcha-spring-boot-starter</artifactId>
</dependency>

配置

package com.huoranger.dlink.config;import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.Properties;/*** @author huoranger* @since 2025-09-05*/
@Configuration
public class CaptchaConfig {/*** 验证码配置* Kaptcha配置类名** @return*/@Bean@Qualifier("captchaProducer")public DefaultKaptcha kaptcha() {DefaultKaptcha kaptcha = new DefaultKaptcha();Properties properties = new Properties();
//    properties.setProperty(Constants.KAPTCHA_BORDER, "yes");
//    properties.setProperty(Constants.KAPTCHA_BORDER_COLOR, "220,220,220");
//    //properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "38,29,12");
//    properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "147");
//    properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "34");
//    properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "25");
//    //properties.setProperty(Constants.KAPTCHA_SESSION_KEY, "code");//验证码个数properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
//    properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Courier");//字体间隔properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE,"8");//干扰线颜色
//    properties.setProperty(Constants.KAPTCHA_NOISE_COLOR, "white");//干扰实现类properties.setProperty(Constants.KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");//图片样式properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.WaterRipple");//文字来源properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "0123456789");Config config = new Config(properties);kaptcha.setConfig(config);return kaptcha;}
}

接口,使用浏览器指纹作为redis 的key,与客户端进行绑定:

    /*** 生成验证码*/@GetMapping("captcha")public void getCaptcha(HttpServletRequest request, HttpServletResponse response){String captchaText = producer.createText();log.info("验证码内容:{}",captchaText);// 存储Redis,配置过期时间redisTemplate.opsForValue().set(getCaptchaKey(request), captchaText, CAPTCHA_CODE_EXPIRED, TimeUnit.MILLISECONDS);BufferedImage image = producer.createImage(captchaText);try (ServletOutputStream outputStream = response.getOutputStream();){ImageIO.write(image,"jpg", outputStream);outputStream.flush();} catch (IOException e) {log.info("获取流出错:{}",e.getMessage());}}/*** 发送短信验证码* @return*/@PostMapping("/send_code")public ResponseData sendCode(@RequestBody SendCodeRequest sendCodeRequest, HttpServletRequest request){String key = getCaptchaKey(request);String cacheCaptcha = redisTemplate.opsForValue().get(key);String captcha = sendCodeRequest.getCaptcha();if (cacheCaptcha != null && cacheCaptcha.equalsIgnoreCase(captcha)){//成功redisTemplate.delete(key);return notifyService.sendCode(SendCodeEnum.USER_REGISTER,sendCodeRequest.getTo());}else {return ResponseData.buildResult(BizCodeEnum.CODE_ERROR);}}private String getCaptchaKey(HttpServletRequest request){String ip = CommonUtil.getIpAddr(request);String userAgent = request.getHeader("User-Agent");String key = "account-service:captcha:" + CommonUtil.MD5(ip + userAgent);log.info("验证码key:{}", key);return key;}

防刷之禁止重复发送短信

  • 60秒后才可以᯿新发送短信验证码
  • 发送的短信验证码10分钟内有效

方案:
⽅式⼀:前端增加校验倒计时,不到60秒按钮不给点击

  • 简单
  • 不安全,存在绕过的情况

⽅式⼆:增加Redis存储,发送的时候设置下额外的key,并且60秒后过期

  • ⾮原⼦操作,存在不⼀致性
  • 增加的额外的key - value存储,浪费空间

⽅式三:基于原先的key拼装时间戳

  • 好处:满⾜了当前节点内的原⼦性,也满⾜业务需求
 @Overridepublic ResponseData sendCode(SendCodeEnum sendCodeEnum, String to) {String cacheKey = String.format(RedisKey.CHECK_CODE_KEY,sendCodeEnum.name(),to);String cacheValue = redisTemplate.opsForValue().get(cacheKey);//如果不为空,再判断是否是60秒内重复发送 0122_232131321314132if (StringUtils.isNotBlank(cacheValue)){long ttl = Long.parseLong(cacheValue.split("_")[1]);//当前时间戳-验证码发送的时间戳,如果小于60秒,则不给重复发送long leftTime = CommonUtil.getCurrentTimestamp() - ttl;if (leftTime < (60 * 1000)){log.info("重复发送短信验证码,时间间隔:{}秒",leftTime);return ResponseData.buildResult(BizCodeEnum.CODE_LIMITED);}}String code = CommonUtil.getRandomCode(6);//生成拼接好验证码String value = code + CommonUtil.getCurrentTimestamp();redisTemplate.opsForValue().set(cacheKey, value, CODE_EXPIRED, TimeUnit.MILLISECONDS);if (CheckUtil.isEmail(to)){//发送邮箱验证码  TODO}else if (CheckUtil.isPhone(to)){//发送手机验证码smsComponent.send(to, smsConfig.getTemplateId(),code);}return ResponseData.buildSuccess();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/98374.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/98374.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/98374.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【RabbitMQ】----RabbitMQ 的7种工作模式

1.Simple(简单模式) P:⽣产者,也就是要发送消息的程序 C:消费者,消息的接收者 Queue:消息队列,图中⻩⾊背景部分.类似⼀个邮箱,可以缓存消息;⽣产者向其中投递消息,消费者从其中取出消息. 特点:⼀个⽣产者P&#xff0c;⼀个消费者C,消息只能被消费⼀次.也称为点对点(Point-to-P…

今日分享:C++ -- list 容器

&#x1f60e;【博客主页&#xff1a;你最爱的小傻瓜】&#x1f60e; &#x1f914;【本文内容&#xff1a;C list容器 &#x1f60d;】&#x1f914; --------------------------------------------------------------------------------------------------------------------…

【Python】数据可视化之分布图

分布图主要用来展示某些现象或数据在地理空间、时间或其他维度上的分布情况。它可以清晰地反映出数据的空间位置、数量、密度等特征&#xff0c;帮助人们更好地理解数据的内在规律和相互关系。 目录 单变量分布 变量关系组图 双变量关系 核密度估计 山脊分布图 单变量分布…

DDD+WebAPI实战

DDD+WebAPI实战 DDD(领域驱动设计,Domain-Driven Design)是一种面向对象的设计方法,它强调将业务逻辑封装在模型中,并通过这些模型来驱动整个应用的设计。在.NET环境中,特别是在使用ASP.NET Core和Web API构建应用时,DDD可以帮助我们更好地组织代码,使得业务逻辑更加清…

人力资源管理的思维方法学习笔记1

北京师范大学政府管理学院1.课程介绍&#xff1a; 讲述视角上&#xff0c;本课程侧重人力资源管理的思维方式&#xff0c;即人力资源管理理论和时间的不同视角和主导范式的分析。这既是对人力资源管理理论发展的凝练&#xff0c;也是对人力资源管理实践演进过程的总结。对于把握…

适应新环境:Trae编辑器下的IDEA快捷键定制

介绍&#xff1a;学习如何在Trae编辑器中配置IntelliJ IDEA风格的快捷键&#xff0c;减少开发环境间的切换成本&#xff0c;提升编码效率。通过安装插件或手动调整&#xff0c;让你更快适应新工具大家好&#xff0c;我是凯哥Java本文标签&#xff1a;代码编辑效率、Trae快捷键、…

基于YOLO8的汽车碰撞事故检测系统【数据集+源码+文章】

基于YOLOv8和Streamlit的汽车碰撞事故检测系统 文末附下载地址 开发目的 随着城市化进程的加快和机动车保有量的持续攀升&#xff0c;道路交通安全问题日益突出&#xff0c;汽车碰撞事故频发不仅严重威胁驾乘人员的生命安全&#xff0c;也对公共秩序、应急响应效率及交通管理…

Unity FARO 测量臂:从零构建实时数字孪生系统

前言:当精准测量遇见实时渲染 在高端制造、质量检测和逆向工程领域,法奥 (FARO) 测量臂是精准的代名词。它能以亚毫米级的精度捕捉现实世界中的三维坐标。现在,想象一下,如果我们将这种精度与 Unity 的强大实时渲染能力结合起来,会发生什么? 我们将得到一个数字孪生 (D…

延迟 队列

概念 延迟队列顾名思义就是消息不立即发送给消费者消费&#xff0c;而是延迟一段时间再交给消费者。 RabbitMQ本身没有直接支持延迟队列的的功能&#xff0c;但是可以通过前面所介绍的TTL死信队列的方式组合 模拟出延迟队列的功能. RabbitMQ 有些版本还支持延迟队列的插件安…

Windows+Docker一键部署CozeStudio私有化,保姆级

在 ​Windows环境​ 下&#xff0c;通过docker&#xff0c;使用 ​火山引擎Doubao-Seed-1.6模型&#xff0c;面向 ​小白新手​ 的 ​Coze Studio私有化部署详细步骤。整个过程分为四大阶段&#xff0c;包含每一步的指令、成功标志。 Coze Studio 私有化部署指南&#xff08;W…

【HEMCO Reference Guide 参考指南第二期】配置文件的结构和语法

配置文件的结构和语法 HEMCO 配置文件的结构和语法(The HEMCO configuration file) 1. Settings(设置) 2. Extension Switches(扩展模块开关) 3. Base Emissions(基础排放配置) 4. Scale Factors(缩放因子) 5. Masks(掩膜区域) 6. Data Collections(数据集合) 参…

01.单例模式基类模块

一、单例模式的构成1、私有的静态成员变量2、公共的静态成员属性或方法3、私有构造函数using System.Collections; using System.Collections.Generic; using UnityEngine;public class BaseManager : MonoBehaviour {void Start(){}// Update is called once per framevoid Up…

[网络入侵AI检测] 深度前馈神经网络(DNN)模型

第4章&#xff1a;深度前馈神经网络&#xff08;DNN&#xff09;模型 欢迎回来&#x1f43b;‍❄️ 在第1章&#xff1a;分类任务配置&#xff08;二分类 vs. 多分类&#xff09;中&#xff0c;我们学习了如何配置模型以回答不同类型的问题&#xff1b;在第2章&#xff1a;数…

【目录-多选】鸿蒙HarmonyOS开发者基础

All look at the answer 针对包含文本元素的组件&#xff0c;例如Text、Button、TextInput等&#xff0c;可以使用下列哪些属性关于ForEach(arr, itemGenerator, index)组件的描述正确的是下面哪些容器组件是可以滚动的关于Tabs组件和TabContent组件&#xff0c;下列描述正确的…

第一讲 Vscode+Python+anaconda 安装

1、vscode下载和安装官网下载最新版&#xff1a;https://code.visualstudio.com/Download注&#xff1a;文件夹最好不要出现中文和空格 2、将vscode修改为中文环境注意&#xff1a;右下角弹出提示框&#xff0c;点击“yes”若不慎关闭了对话框&#xff0c;也不要紧&#xff0c;…

《sklearn机器学习——回归指标2》

均方对数误差&#xff08;mean_squared_log_error函数&#xff09; mean_squared_log_error函数计算与平方&#xff08;二次方&#xff09;对数误差或损失的期望值相一致的风险指标。 Mean Squared Logarithmic Error 参数与返回值 函数简介 mean_squared_log_error 是用于计算…

当电力设计遇上AI:良策金宝AI如何重构行业效率边界?

在工程设计行业&#xff0c;我们常说“经验为王”。一个资深工程师的价值&#xff0c;往往体现在他对规范的熟悉、对计算的把握、对图纸的掌控。但今天&#xff0c;这个“王座”正在被重新定义。不是经验不重要了&#xff0c;而是——效率的边界&#xff0c;正在被AI重构。以良…

【深度学习】重采样(Resampling)

在深度学习的背景下&#xff0c;重采样主要涉及两个方面&#xff1a; 数据层面的重采样&#xff1a;处理不平衡数据集。模型层面的重采样&#xff1a;在神经网络内部进行上采样&#xff08;UpSampling&#xff09;或下采样&#xff08;DownSampling&#xff09;&#xff0c;常见…

计算机实现乘法运算的方式---ChatGPT 5 thinking作答

计算机如何实现“乘法” 下面分层次把乘法在数据表示 → 整数硬件/软件 → 大整数 → 浮点数 → 特殊场景里的主流实现方式讲清楚&#xff0c;并给出取舍建议与简单伪代码。0&#xff09;前置&#xff1a;数的表示 无符号整数&#xff1a;按二进制位权求值。有符号整数&#xf…

Ubuntu 安装 / 配置 VNC

一、基础环境准备 1. 更新 sudo apt update 2. 安装 VNC 服务器 & 轻量桌面(XFCE) # 安装 TightVNC 服务器 + XFCE 桌面(推荐轻量方案) sudo apt install tightvncserver xfce4 xfce4-goodies xterm -y二、核心配置:让 VNC 加载桌面环境 1. 初始化 VNC 密码(首次…