SpringBoot+Redis如何实现用户输入错误密码后限制登录(含源码)
点击下载《SpringBoot+Redis如何实现用户输入错误密码后限制登录(含源码)》
1. 引言
在当今的网络环境中,保障用户账户的安全性是非常重要的。为了防止暴力破解和恶意攻击,我们需要在用户尝试登录失败一定次数后限制其登录。这不仅可以保护用户的账户安全,还可以减轻服务器的压力。在本文中,我们将使用Spring Boot和Redis来实现这个功能。

2. 系统设计
首先,我们需要一个系统来跟踪用户的登录尝试。由于我们的系统需要处理大量的用户请求,所以我们需要一个快速、可靠的存储系统来存储这些信息。Redis是一个内存中的数据结构存储,它可以提供高速的读写操作,非常适合我们的需求。
我们的系统将使用Redis的哈希数据类型来存储每个用户的登录尝试信息。哈希中的每个字段表示一个尝试的计数器,而字段的值则表示尝试的次数。当用户尝试登录时,我们会增加相应的计数器。如果计数器的值超过了设定的限制,我们将阻止用户在设定的时间内再次尝试登录。
3. 实现细节
3.1 添加依赖
首先,我们需要在Spring Boot项目中添加Redis的依赖。在pom.xml文件中添加以下依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.2 配置连接信息
然后,我们需要在application.properties文件中配置Redis的连接信息:
spring.redis.host=your_redis_host
spring.redis.port=your_redis_port
3.3 连接Redis
接下来,我们需要创建一个RedisTemplate来连接Redis:
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); return template;
}
3.4 创建RedisService
然后,我们需要创建一个RedisService来处理与Redis的交互:
@Service
public class RedisService { @Autowired private StringRedisTemplate redisTemplate; public void incrementKey(String key) { redisTemplate.opsForValue().increment(key, 1); } public long getKey(String key) { return redisTemplate.opsForValue().get(key); }
}
3.5 创建UserController
现在,我们可以在UserController中实现登录功能:
@RestController
public class UserController { @Autowired private UserService userService; @Autowired private RedisService redisService; @Autowired private AuthenticationManager authenticationManager; @PostMapping("/login") public ResponseEntity<?> login(@RequestBody User user) { // 检查用户名和密码是否正确 if (userService.checkUser(user.getUsername(), user.getPassword())) { // 检查用户是否被阻止登录 long attempts = redisService.getKey("login_attempts_" + user.getUsername()); if (attempts >= 3) { // 用户尝试登录次数超过3次,阻止用户登录一定时间(例如30分钟) redisService.incrementKey("login_attempts_" + user.getUsername()); // 增加尝试次数计数器(在一定时间后过期) return ResponseEntity.status(HttpStatus.FORBIDDEN).body("You have exceeded the maximum login attempts. Please wait for 30 minutes and try again."); } else { // 用户没有被阻止登录,允许他们登录并重置尝试次数计数器(在一定时间后过期) redisService.set("login_attempts_" + user.getUsername(), 0, 30, TimeUnit.MINUTES); // 设置计数器在30分钟后过期(例如30分钟) userService.loginUser(user); // 允许用户登录并重置尝试次数计数器(在一定时间后过期) return ResponseEntity.status(HttpStatus.OK).body("Login successful."); } } else { // 如果用户名和密码不正确,增加尝试次数计数器并返回错误信息给用户。如果用户已经被阻止登录,则返回错误信息给用户。否则,允许用户再次尝试登录。重复这个过程直到用户成功登录或被阻止登录。 redisService.incrementKey("login_attempts_" + user.getUsername()); // 增加尝试次数计数器 return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid username or password."); } }
}
4. 测试与验证
为了验证我们的系统是否正常工作,我们需要编写一些测试用例。我们可以使用JUnit和MockMvc进行测试。以下是一个简单的测试用例,用于测试登录功能:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerTest { @Autowired private WebApplicationContext context; @Autowired private UserService userService; @Autowired private RedisService redisService; private MockMvc mockMvc; @Before public void setup() { mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); } @Test public void testLoginSuccess() throws Exception { mockMvc.perform(post("/login") .contentType(MediaType.APPLICATION_JSON) .content("{\"username\":\"test\",\"password\":\"test\"}")) .andExpect(status().isOk()); long attempts = redisService.getKey("login_attempts_" + "test"); assertEquals(0, attempts); // 确保尝试次数计数器被重置为0 } @Test public void testLoginFailureAndBlock() throws Exception { mockMvc.perform(post("/login") .contentType(MediaType.APPLICATION_JSON) .content("{\"username\":\"test\",\"password\":\"test\"}")) .andExpect(status().isOk()); mockMvc.perform(post("/login") .contentType(MediaType.APPLICATION_JSON) .content("{\"username\":\"test\",\"password\":\"test\"}")) .andExpect(status().isForbidden()); // 用户被阻止登录,返回403错误 long attempts = redisService.getKey("login_attempts_" + "test"); assertEquals(3, attempts); // 确保尝试次数计数器被设置为3,表示用户已被阻止登录 }
}
5. 总结
总结一下SpringBoot + Redis实现用户连续输入多次密码错误后限制登录的原理和作用如下:
-
原理:
-
当用户尝试登录时,系统会检查Redis中是否存在该用户的登录尝试记录。
-
如果记录存在,则判断用户连续输入密码错误的次数,并根据设定的阈值决定是否限制用户登录。
-
如果达到阈值,则在Redis中设置一个标志位,表示该用户已被限制登录。
-
在限制期间内,系统将拒绝该用户的登录请求。
-
限制时间过后,系统将自动解除对该用户的限制。
-
-
作用:
-
增强系统安全性:通过限制用户连续输入密码错误的次数,可以防止暴力破解攻击,保护用户账户安全。
-
提高用户体验:对于因连续输入密码错误而被限制登录的用户,系统会给出相应的提示信息,引导用户重置密码或找回账号,避免用户因多次尝试而产生挫败感。
-
防止恶意行为:对于恶意尝试登录的用户,系统可以实施限制登录的策略,有效地遏制了其不良行为。
-
优化服务器性能:通过Redis实现用户登录限制,可以减轻服务器的压力,提高系统的性能和稳定性。
-
点击下载《SpringBoot+Redis如何实现用户输入错误密码后限制登录(含源码)》
相关文章:
SpringBoot+Redis如何实现用户输入错误密码后限制登录(含源码)
点击下载《SpringBootRedis如何实现用户输入错误密码后限制登录(含源码)》 1. 引言 在当今的网络环境中,保障用户账户的安全性是非常重要的。为了防止暴力破解和恶意攻击,我们需要在用户尝试登录失败一定次数后限制其登录。这不…...
kotlin中的初始化问题纪录
1. init 代码块的顺序问题 init代码块和成员变量实质上是按先后顺序执行的。若果init{} 中有成员变量使用。要把成员变量放到代码块之前。 2. init代码块之中的函数问题 下面是一段错误的代码: class mkotlin{val info:Stringinit {getInfoMethod()info "adad…...
Web中的转发与重定向
转发与重定向 一、转发和重定向的概念1.转发2.重定向 二、JavaWeb 中的转发和重定向三、SpringMVC 中的转发和重定向1.转发(1) 默认的方式(2) 完整的方式 2.重定向 四、总结 一、转发和重定向的概念 在 Web 应用中,转发和重定向都是用于将请求从一个页面传递到另一…...
交叉注意力融合时域、频域特征的FFT + CNN-Transformer-CrossAttention轴承故障识别模型
目录 往期精彩内容: 前言 1 快速傅里叶变换FFT原理介绍 第一步,导入部分数据 第二步,故障信号可视化 第三步,故障信号经过FFT可视化 2 轴承故障数据的预处理 2.1 导入数据 2.2 制作数据集和对应标签 3 交叉注意力机制 …...
STM32读取MPU6050数据并通过角度值控制舵机运动(STM32、GY-521 MPU6050、SG90舵机、MG946舵机)
通过STM32F103C8T6读取MPU6050数据控制舵机运动(STM32、GY-521 MPU6050、SG90舵机、MG946舵机) 最终现象一、MPU6050数据读取二、舵机控制原理①什么是PWM?②STM32F103C8T6如何生成PWM?③控制舵机需要什么样的PWM波? 三…...
Unity_Playable工具使用
Unity_Playable工具使用 目录 Unity_Playable工具使用 1. Default Playables(Timeline扩展) 2. PlayableGraph Visualizer&#x...
Flutter canvas 画一条波浪线 进度条
之前用 Flutter Canvas 画过一个三角三角形,html 的 Canvas 也画过一次类似的, 今天用 Flutter Canvas 试了下 感觉差不多: html 版本 大致效果如下: 思路和 html 实现的类似: 也就是找出点的位置,使用二阶…...
Java技术栈 —— Spring MVC 与 Spring Boot
参考文章或视频链接[1] Spring vs. Spring Boot vs. Spring MVC[2] Key Differences Between Spring vs Spring Boot vs Spring MVC...
跟着cherno手搓游戏引擎【16】Camera和Uniform变量的封装
相机封装: OrthographicCamera.h: #pragma once #include <glm/glm.hpp> namespace YOTO {class OrthographicCamera{public:OrthographicCamera(float left,float right , float bottom,float top);const glm::vec3& GetPosition()const { return m_Pos…...
微服务中间件 RabbitMq学习
1、为什么需要Mq 例如在用户注册业务中,用户注册成功后 需要发注册邮件和注册短信,传统的做法有两种 1.串行的方式;2.并行的方式 ; 假设三个业务节点分别使用50ms,串行方式使用时间150ms,并行使用时间10…...
3D Gaussian Splatting-实时辐射场渲染技术
引用自:https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/3d_gaussian_splatting_high.pdf 概述: 该论文介绍了一种用于实时辐射场渲染的3D高斯点渲染技术。 其基本原理是: 一:首先从SfM校准的图像及其对应的稀疏点云…...
vue中nextTick()
在 Vue.js 中,nextTick() 是一个非常有用的方法,用于在下一个 DOM 更新循环结束后执行延迟回调。这在你需要读取或写入刚刚更新的 DOM 时非常有用。 下面是一个简单的示例代码,用于解析 nextTick() 的用法: <template> &…...
Redis 布隆过滤器
布隆过滤器 这一篇文章主要是记录布隆过滤器的使用和认识 主要参考了如下的blog https://blog.csdn.net/weixin_42972832/article/details/131211665 他讲的还不错 简单的来说,布隆过滤器,实际上就像是一个集合,拿redis的key来举例来说,布隆过滤器的设置就是去过滤不属于redi…...
中国的茶文化:现代生活中的茶文化
中国的茶文化:现代生活中的茶文化 引言 在现代社会的快节奏生活中,茶文化并未随时间流逝而褪色,反而以其独特的方式融入了全球各地人们的日常生活。它超越了饮品本身的范畴,成为一种连接历史、人文与现代生活方式的艺术形式。本文…...
Python正则表达式语法
正则表达式是一种强大的文本处理工具,它可以用来搜索、匹配和替换特定的字符模式。在Python中,正则表达式常常被用于处理字符串数据,例如文本搜索、数据提取、格式验证等任务。本文将深入介绍Python中正则表达式的语法,帮助读者全…...
C++核心编程:文件操作 笔记
5.文件操作 程序运行时产生的数据都属于临时数据,程序一旦允许结束都会被释放。通过文件可以将数据持久化 C中对文件操作需要包含头文件<fstream> 文件类型分为两种: 文本文件 - 文件以文本的ASCII码形式存储在计算机中二进制文件 - 文件以文本…...
ElementUI组件:Button 按钮
ElementUI安装与使用指南 Button按钮 点击下载learnelementuispringboot项目源码 效果图 el-button.vue页面效果图 项目里el-button.vue代码 <script> export default {name: "el_button",// 注意这里的名称不能和 router inex.js里的name一样methods: {s…...
#RAG|NLP|Jieba|PDF2WORD# pdf转word-换行问题
文档在生成PDF时,文宁都发生了什么。本文讲解了配置对象、resources对象和content对象的作用,以及字体、宇号、坐标、文本摆放等过程。同时,还解释了为什么PDF转word或转文字都是一行一行的以及为什么页眉页脚的问题会加大识别难度。最后提到了文本的编码和PDF中缺少文档结构标…...
solr的原理是什么
1 Java程序里如果有无限for循环的代码导致CPU负载超高,如何排查? 排查Java程序中由于无限循环导致的CPU负载过高的问题,可以按照以下步骤进行: 资源监控: 使用系统命令行工具(如Linux上的top或htop…...
【安装指南】nodejs下载、安装与配置详细教程
目录 🌼一、概述 🍀二、下载node.js 🌷三、安装node.js 🍁四、配置node.js 🌼一、概述 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,用于构建可扩展的网络应用程序。Node.js 使用事件驱动、…...
Unity安装包瘦身实战:从2.3GB到680MB的工程化治理
1. 为什么一个500MB的Unity项目打包后会变成3GB?——安装包膨胀的真实逻辑“Unity安装包减肥”这六个字,听起来像在给软件做瑜伽,但实际是每个上线前夜都在咬牙硬扛的生存战。我做过7个已上线的Unity手游项目,最深的体会是&#x…...
Lindy企业流程自动化实施全周期拆解:从0到1上线仅需14天的关键5步法
更多请点击: https://intelliparadigm.com 第一章:Lindy企业流程自动化实施全周期拆解:从0到1上线仅需14天的关键5步法 Lindy 作为轻量级、高可扩展的流程自动化平台,其核心优势在于将复杂的企业级RPA与低代码逻辑深度融合&#…...
AlphaStar强化学习工程范式:从星际争霸到工业决策
1. 这不是“下棋”的升级版:AlphaStar 的强化学习到底在学什么? 很多人第一次听说 AlphaStar,第一反应是:“哦,又一个打败人类的AI,跟 AlphaGo 差不多吧?”——这个理解偏差非常典型࿰…...
ARM嵌入式C#开发实战:基于SkiaSharp的低延迟GUI实现
1. 这不是玩具,是ARM嵌入式系统能力的“压力测试仪”很多人第一次听说“在ARM开发板上跑C#游戏”,第一反应是:这能行?C#不是Windows桌面和服务器的语言吗?Mono?.NET Core?ARM板子连图形驱动都配…...
AssetStudio深度解析:Unity序列化协议与产线级资源解包实战
1. 这不是“又一个AssetStudio教程”,而是我用它救回三个项目的真实记录AssetStudio、Unity资源提取、AssetBundle解包——这几个词,对做过Unity客户端开发、逆向分析、MOD制作或老游戏复刻的人来说,不是工具名,是救命稻草。我第一…...
鸿蒙electron跨端框架PC简序实战:把轻任务、优先级和截止时间塞进一张桌面清单
前言 欢迎加入鸿蒙PC开发者社区,共同打造开发者工具生态:鸿蒙PC开发者社区 :https://harmonypc.csdn.net/ 开源地址:https://AtomGit.com/lqjmac/ele-shixu?source_modulesearch_project 写 简序 时,我没有把它当成…...
基于改进粒子群算法的混合储能系统容量优化附Matlab代码
✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、程序设计科研仿真。🍎完整代码获取 定制创新 论文复现点击:Matlab科研工作室👇 关注我领取海量matlab电子书和数学建模资料 dz…...
GQA:多查少算的 Attention 头组合
本文基于昇腾CANN和昇腾NPU,围绕 ops-transformer 仓库的相关技术展开。 MHA(Multi-Head Attention)每个 Head 一套 QKV——8 个 Head 就是 8 组。MQA 省过头了——8 个 Head 共享 K、V。GQA(Grouped Query Attention)…...
选型必读丨高温定向传感器采购与使用的真实成本分析
在定向钻井设备采购决策中,价格往往不是唯一的考量因素。很多用户关注的是高温定向传感器的全生命周期总成本(TCO, Total Cost of Ownership)以及最终能带来怎样的投资回报(ROI)。本文将从专业角度,系统分析…...
深度学习分段逼近实战:激活函数硬件友好型实现指南
1. 项目概述:为什么“分段逼近”不是数学游戏,而是深度学习落地的命脉“Mastering Deep Learning: The Art of Approximating Non-Linearities with Piecewise Estimations Part-2”——这个标题里藏着一个被太多教程刻意绕开的真相:深度学习…...
