网站首页 > 技术文章 正文
前言
我们在很多系统登录时中看到连续输错次数达到3次或5次后,账号会被锁定一段时间,有的是3分钟,有的是5分钟,有的甚至是限制当天都不能重新尝试(比如银行、支付宝等),只有达到相应的时间限制后才能继续尝试,类似下图,那么这种效果是如何实现的呢?
需求分析
其实这种需求在我们实际开发中会经常遇到,这是常规登录的一种安全性加强措施,防止有人恶意对账号密码进行爆破,特别是一些重要系统或管理员账号等高级别权限的情况。
首先我们先分析登录认证流程,用户输入账号密码登录-后端判断-成功则继续请求-失败则返回前端要求重新登录,流程非常简单。
而要加上锁定账号限制,我们肯定优先在后端实现,主要流程有以下变化:
- 登录请求时先判断账号是否锁定;
- 密码错误时先判断是连续几次错误;
- 错误不超过5次则返回密码错误信息,超过5次后后台锁定账号,用户再次登录时,不管哪个终端不管密码是否正确都会提示锁定。
所以,新的登录认证流程就变成了下图:
解决思路
其实解决方案有很多种,比如在后端用户表中加上错误次数,是否锁定,锁定开始时间,锁定解决时间等,每次请求时进行数据库的读写,但是这样无疑增加了读写的请求量,操作起来也不便捷,今天给大家介绍一种简单实现方法,采用Sa-token认证框架,主要应用到的API其实只有4个,只要灵活应用就可以实现我们的需求。
//锁定账号,第一个参数是用户ID,第二个是锁定时间,单位是秒
StpUtil.disable(userId,time)
//判断账号是否锁定
StpUtil.isDisable(userId)
//会话中设置某个参数,在设置超时次数时会用到
session.set(key,value)
//获取会话中某个参数
session.get(key)
具体实现代码如下:
@RequestMapping("/login")
public SaResult login(String usrname,String pass){
SaSession session=StpUtil.getSessionByLoginId(usrname);
int errorCount=session.getInt("errCount");
String errorUsr=session.getString("usrname");
//判断当前账号是否是上一个输入错误的账号
if(!usrname.equals(errorUsr)){
session.set("usrname",usrname);
errorCount=0;
session.set("errCount",0);
}
//如果密码正确,且未锁定,进行登录,这是密码设置123456,实际认证时会请求数据库
if(!StpUtil.isDisable(usrname)&&"123456".equals(pass)){
StpUtil.login(usrname);
session.set("usrname",usrname);
session.set("errCount",0);
return SaResult.ok("登录成功!");
} else
//如果当前账号已锁定,或当前账号输入错误超过5次,提示锁定信息
if(StpUtil.isDisable(usrname)||(usrname.equals(errorUsr)&&errorCount>=5)){
//如果是第一次锁定,锁定300秒
if(!StpUtil.isDisable(usrname))StpUtil.disable(usrname,5*60);
//返回锁定剩余时长
return SaResult.error(String.format("密码错误超过5次,账号已锁定,请%d秒钟后再试",StpUtil.getDisableTime(usrname) ));
}
//错误次数+1
else {
errorCount++;
session.set("errCount",errorCount);
}
return SaResult.data(String.format("账号或密码错误,请重试,错误次数%d", errorCount));
}
我这里为了更贴近实际开发,返回消息体采用了SaResult进行了封装,提示信息可根据实际需求进行修改。
系统运行效果
为了测试效果,我做了个简单的登录页面,包括账号,密码两个输入框,实际开发中采用已有登录页面即可。
密码输入错误时,提示已连续错误次数:
密码输入错误超过5次时,锁定账号,提示剩余时间:
达到时间后自动解除锁定,再输入正确密码,提示登录成功
可以看到,我们自己要写的代码其实并不多,也没有与后端数据库,如果是大用户量的情况下,还可以集成redis框架。
猜你喜欢
- 2025-06-18 SQL注入:程序员亲手打开的潘多拉魔盒,如何彻底封印它?
- 2025-06-18 Java项目本地部署宝塔搭建实战Java物业小程序源码物业系统源码
- 2025-06-18 如何安全地保障用户Web登录安全?(web登录安全方案)
- 2025-06-18 如何发个 npm 包?(npm发包流程)
- 2025-06-18 大华信息安全|WEB和Configtool密码重置
- 2025-06-18 某实战项目登录口处的渗透测试(渗透实战测试平台)
- 2025-06-18 Spring Boot 中密码加密的两种姿势
- 2024-10-04 用户名或密码不正确?锁定? 用户名或密码不正确,请重新输入!
- 2024-10-04 通过sql注入获取用户名和密码 192.168.1.1路由器登录入口用户名和密码
- 2024-10-04 常见的密码攻击方式及防范措施 密码攻击是什么
你 发表评论:
欢迎- 533℃Oracle分析函数之Lag和Lead()使用
- 531℃几个Oracle空值处理函数 oracle处理null值的函数
- 529℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 520℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 515℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 505℃【数据统计分析】详解Oracle分组函数之CUBE
- 485℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 483℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端富文本编辑器 (47)
- 前端路由 (61)
- 前端数组 (73)
- 前端排序 (47)
- 前端密码加密 (47)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)