项目实战:防刷

news2025/1/4 14:33:29

  你好,我是田哥

最近在搞充电桩项目,用户使用短信验证码形式进行注册和登录,那么问题来了?

分布式微服务项目实战:充电桩项目

实战分布式事务【Seata+Spring Cloud】

项目实战:自定义异常和统一参数验证(附源码)

如果用户无聊或恶意的一直点发送验证码,虽然每条短信没便宜,但短信量大了,这也是一笔不小的开销的。

因此,我们需要对此做一些限制的策略。

如何限制?这里就不得不提一些限流算法。

限流的常见算法有以下三种:

  • 时间窗口算法

  • 漏桶算法

  • 令牌算法

下面来看看充电桩项目中是如何实现的。

/**
* @author tianwc  公众号:java后端技术全栈、面试专栏
* @version 1.0.0
* @date 2023年05月27日 09:13
* 博客地址:<a href="http://woaijava.cc/">博客地址</a>
*/
@Component
public class LimiterUtil {
@Resource
private RedisTemplate<String, String> redisTemplate;

/**
 * 固定窗口限流算法
 *
 * @return true 限流  false 放行
 */
public boolean fixedWindow(String key, int count) {
    long countCache = redisTemplate.opsForValue().increment(key);
    return countCache > count;
}

/**
 * intervalTime 时间内 最多只能访问5次
 *
 * @param key          缓存key
 * @param currentTime  当前时间  new Date().getTime();
 * @param intervalTime 有效期
 * @param count        限流次数
 * @return true 限流 false 放行
 */
public boolean slidingWindow(String key, Long currentTime, Long intervalTime, int count) {
    //发送次数+1
    redisTemplate.opsForZSet().add(key, UUID.randomUUID().toString(), currentTime);
    // intervalTime是限流的时间
    int countCache = Objects.requireNonNull(redisTemplate.opsForZSet().rangeByScore(key, currentTime - intervalTime, currentTime)).size();
    return countCache > count; 
}
}

发送短信单位时间内次数限制采用的是slidingWindow()方法的参数。

调用案例:

service层代码:

public CommonResult<Boolean> sendCode(String phone, String codeCachePre, Integer msgType) {
        if (StringUtil.isEmpty(phone)) {
            return CommonResult.failed(ResultCode.VALIDATE_FAILED);
        }
        ParamValidate.isNull(phone, "phone参数为空");
        //同一个手机号码 发送次数限流
        //同一个手机号每秒 最多只能发5次
        boolean limit = limiterUtil.slidingWindow(RedisConstantPre.MESSAGE_LIMIT_KEY_PRE + phone, (new Date()).getTime(), 60000L, 5);
        if (limit) {
            return CommonResult.failed(ResultCode.SEND_MESSAGE_LIMIT);
        }
        CommonResult<MessageTemplateDto> commonResult = messageTemplateFeignClient.queryByMessageType(msgType);
        if (commonResult.getCode() != ResultCode.SUCCESS.getCode()) {
            log.error("短信模板不存在,tye={}", msgType);
            return CommonResult.failed(ResultCode.VALIDATE_FAILED);
        }
        MessageTemplateDto messageTemplateDto = commonResult.getData();
        //生成随机验证码
        String code = RandomUtil.randomNumbers(6);
        log.info("登录发送验证码:{}", code);
        //发送验证码
        String content = messageTemplateDto.getContent();
        //验证码占位符
        String newContent = content.replace(messageTemplateDto.getContentParam(), code);
        //调用MQ  异步发送短信验证码
        phoneMessageProducer.sendPhoneMessage(phone, newContent);
        //存到redis中 设置有效期 60秒
        //60秒后需要重现发送
        redisConfig.set(codeCachePre + phone, code, 60);
        return CommonResult.success(Boolean.TRUE);
    }

画个图 更好地理解:

969626aed1f453987be6fe25bc0d0901.png

controller层代码:

/**
 * 发送登录手机验证码
 */
@PostMapping("/sendCode")
public CommonResult<Boolean> sendCode4Login(@RequestBody SendCodeReqDto sendCodeReqDto) {
  return sendCodeService.sendCode(sendCodeReqDto.getPhone(), RedisConstantPre.SEND_CODE_LOGIN_PRE, MessageTemplateTypeEnums.PAY_SUCCESS_TEMPLATE.getType());
}

测试

POST

http://localhost:9006/user/sendCode

Content-Type: application/json; charset=UTF-8

{
  "code": 400015,
  "message": "短信发送太频繁,请隔一会再发送!",
  "data": null
}

好了,今天就分享这么多。

如果有需要简历修改、简历优化、简历包装、面试辅导、模拟面试、技术辅导、技术支持等,欢迎加我微x(tj20120622)。

个人技术博客可刷题:http://woaijava.cc/

回复77 ,获取《面试小抄2.0版》

回复电子书,获取后端必读的200本电子书籍

文章推荐

中厂,面试就问了4道题,凉了!

分布式问题,你知道几个?

应届生,实力已超6年,太卷了!

手把手教你写简历,包装、优化!

面试不问java,问MySQL,如何破局?

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

lazarus开发:快速读写excel文件的神奇控件——FPSpreadsheet

目录 1 简介 2 用wps制作一个简单的工资表 3 编译一下自带的演示程序 1 简介 FPSpreadsheet是一个功能强大的控件库&#xff0c;用于读取和写入电子表格文件。使用该控件库开发的软件&#xff0c;能够在不安装电子表格应用程序的情况下&#xff0c;快速读出、写入电子表格文…

详解Hystrix

目录 1.微服务中的容错 1.1.服务雪崩 1.2.解决办法 2.hystrix 2.1.概述 2.2.项目结构及依赖 2.3.代码示例 2.3.1.注册中心 2.3.2.服务调用者 2.3.3.服务提供者 2.4.服务降级 2.4.1.单点响应 2.4.2.默认响应 2.4.3.前置响应 2.5.服务熔断 2.5.1.概述 2.5.2.使用…

【C语言复习】第一篇、关于我的C语言的复习路线

目录 第一部分、前言 第二部分、学习视频 第三部分、我的建议 第一部分、前言 首先想谈一下为啥都读研究生的我还在学习C语言&#x1f602;&#xff0c;说起来我认为挺搞笑的&#xff0c;一句话解释就是&#xff1a;本科上课的时候&#xff0c;耳朵打苍蝇去&#xff0c;哈哈。…

面向快速反应的工程团队--QRF团队模型

很多团队都纠结于产品业务需求和各种不断插入的中断请求而无法自拔&#xff0c;这篇文章介绍了QRF团队模型&#xff0c;将产品业务开发和紧急响应团队区分开&#xff0c;为重要而紧急的事情提供单独的处理通道&#xff0c;从而帮助团队能够聚焦在重要的事情上。原文&#xff1a…

Nucleo-F411RE (STM32F411)LL库体验 7 - 低功耗(睡眠、待机)

Nucleo-F411RE &#xff08;STM32F411&#xff09;LL库体验 7 - 低功耗&#xff08;睡眠&#xff09; 1、简述 F411有三种模式 Sleep mode、stop mode 、standby mode。 其中SleepMode 、Stop Mode 可选择WFI 以及WFE&#xff0c;两者的区别在于&#xff0c;前者任何中断都能…

编译原理笔记(哈工大编译原理)

文章目录 前言概论语言与文法基本概念字母表串字母表与串的联系 文法语言推导和规约句型与句子语言与字母表 文法的分类 前言 说实话&#xff0c;我不是很想上这门课&#xff0c;确实没什么大用&#xff0c;虽然我觉得这门课学一学也挺好&#xff0c;但是我觉得弄8个大实验就真…

socket地址的通配符地址、环回地址

今天在写ServerSocket的时候&#xff0c;遇到了socket地址的通配符地址、环回地址。 package com.thb;import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket;public class ServerSocketMain {public static void main(String[] args) {try…

UI Tool Kit 使用

Unity 2021 已经把UIBuilder 内置了&#xff0c;项目组也打算 后续工具采用 toolkit来写&#xff0c;这边也是找了一下教程熟悉了一下。 UI 工具包 - Unity 手册 首先 先创建一个EditorWindow 会生成相应的C#&#xff0c;UXML,USS代码 默认会把显示的MenuItem代码生成&#xf…

记录--设计一个可选择不连续的时间范围的日期选择器

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 npm包&#xff1a;sta-datepicker效果图 需求 普通的时间选择器要么只能单选&#xff0c;要么只能选范围&#xff0c;不可以随意选择若干个时间&#xff0c;同时大多数现成的时间选择器选择结束会收起…

EasyExcel实战与笔记

概述 Excel导入导出是业务开发中非常常见的需求。本文记录一下如何快速入门使用EasyExcel&#xff0c;深度实战&#xff0c;以及遇到的问题。 入门 使用EasyExcel导入如下依赖即可&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactI…

java-代码生成器——有了代码生成器两个小时的工作量2分钟完成了

代码生成器 &#x1f942;代码生成器&#x1f33b;1. 第一步引用相关依赖&#x1f357;2. 第二步编写代码 CodeGet.java&#x1f969;3. 第三步运行查看结果&#x1f356;4. 第四步总结一下 &#x1f942;代码生成器 只需要创建好表的结构&#xff0c;代码生成器通过简单的配置…

Linux知识点 -- 进程控制(二)

Linux知识点 – 进程控制&#xff08;二&#xff09; 文章目录 Linux知识点 -- 进程控制&#xff08;二&#xff09;一、进程程序替换1.概念2.替换原理3.进程替换的操作4.使用exec函数执行自己写的程序5.使用exec函数执行其他语言的程序 二、编写一个简易的shell 一、进程程序替…

LeetCode 892. Surface Area of 3D Shapes【数组,数学】简单

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

KCC@北京启动,为一个城市做好开源!

KCC&#xff08;开源社城市社区&#xff09;北京区在6月12日正式成立&#xff0c;吸引了众多开源爱好者和技术开发者参与。现场举行的活动围绕 “为一个城市做好开源” 的话题展开讨论&#xff0c;包括开发者关系、开源背后的无用之用、开源在中国的变化、开源的困难与挑战以及…

OpenAI ChatGPT 使用示例

1.编程应用 1.1. 生成例子代码 ChatGPT帮助我们生产我们需要的例子代码。而且准确率很高。即使你不懂某一种语言也没关系&#xff0c;一定程度上较低了程序员的的门槛。 我有三组数据&#xff0c;第一组是星期一到星期五&#xff0c;第二组是这一天的具体时间&#xff0c;第三…

etcd 备份操作---马哥教育

etcd安装&#xff1a; mkdir -pv etcd-download-test tar -zxvf etcd-v3.4.4-linux-amd64.tar.gz -C etcd-download-test/ 编辑修改系统环境变量 /etc/profile export ETCD_HOME/tmp/etcd-download-test/etcd-v3.4.4-linux-amd64 export PATH$PATH:$JAVA_HOME/bin:$ETCD_HOM…

html实现好看的个人介绍,个人主页模板2(附源码)

文章目录 1.设计来源1.1 主界面1.2 关于我界面1.3 项目演示界面1.4 联系我界面 2.效果和源码2.1 动态效果2.2 源代码2.3 源码目录 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/131257976 html实现好看的个人…

老胡的周刊(第095期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 tabby[2] 自托管的 AI 编码助手&#xff0c;…

230617安装SqlServer2017Express后,再安装一个SqlServer2017ExpressAdvanced

230616安装SqlServer2017Express 下载地址 选择语言 Microsoft SQL Server 2017 Express 下载地址: 简体中文 感谢下载 Microsoft SQL Server 2017 Express 获得下载软件 我将下载的文件的名称加上了SHA256值, 一长串 是一个 .exe 的自解压文件, 双击后,默认解压到同根文件夹…