Redis+lua脚本限制ip多次输入错误密码

Redis+lua脚本限制ip多次输入错误密码

不能锁username,因为如果有人恶意保留破解密码的话。会导致用户本人无法登录。
这里我采用 以ip的方式进行锁定。利用redis
设置key:ip。value:当前ip尝试登录的次数

实现逻辑

逻辑简单,假设限制错误次数为5

  1. 用户登录时。判断key是否存在。
  2. 如果key不存在,说明第一次登录。判断密码是否正确,如果正确什么都不干直接返回。如果不正确,设置key为ip,value为1,并设置过期时间,返回错误信息。
  3. 如果存在key,说明之前尝试登录过。判断value是否大于阈值,如果大于阈值刷新过期 并返回错误。如果小于阈值,还要判断密码是否正确如果密码正确,删除key并返回正确信息。如果密码不正确,将key的value值+1并重置过期时间,返回密码错误的信息。

以上主要注意两点
一点是有key的情况下密码正确需要删除key
二是有key的情况下,密码错误或者尝试次数大于阈值再次尝试登录,需要刷新过期时间

使用lua脚本主要保证了对上述逻辑的原子性,因为涉及获取key的值并判断,然后将key的值+1 或 删除key。

实现代码

Service类加载时,加载lua脚本

    private static final DefaultRedisScript<Long> CHECK_LOGIN_SCRIPT;// 类加载时 加载lua脚本static {CHECK_LOGIN_SCRIPT = new DefaultRedisScript<>();CHECK_LOGIN_SCRIPT.setLocation(new ClassPathResource("checkLogin.lua"));CHECK_LOGIN_SCRIPT.setResultType(Long.class);}

具体校验方法,主要逻辑调用了lua脚本

    private void checkLoginInfo(UserLoginContext userLoginContext) {String username = userLoginContext.getUsername();String password = userLoginContext.getPassword();//根据用户名查实体 从数据库RPanUser entity = getRPanUserByUsername(username);if (Objects.isNull(entity)){throw new RPanBusinessException("用户名不存在");}String salt = entity.getSalt();             //获取盐值String encPassword = PasswordUtil.encryptPassword(salt, password) ;  //将前端传 的密码加密String dbPassword = entity.getPassword();   //获取数据库的密码// encPassword 表示前端传过来的 加密后的密码// dbPassword  表示数据库中的   加密后的密码// TODO 调用lua脚本判断 登录失败 登录成功 及锁定ipList<String> keys = new ArrayList<>();String ipAddress = HttpLogEntityBuilder.getIpAddress(userLoginContext.getRequest());    //获取请求ip// key设置为 ip+username,进行锁定keys.add(UserConstants.CHECK_LOGIN_PREFIX + ipAddress + "_" + username);// 执行lua脚本Long result = (Long)redisTemplate.execute(CHECK_LOGIN_SCRIPT, keys, encPassword, dbPassword, UserConstants.CHECK_LOGIN_THRESHOLD, UserConstants.CHECK_LOGIN_EXPIRE);if (result == 0){throw new RPanBusinessException("用户名或密码不正确");}if (result == -1){throw new RPanBusinessException("输入密码错误达到"+UserConstants.CHECK_LOGIN_THRESHOLD+"次,请1分钟后尝试");}
//        if (!Objects.equals(encPassword, dbPassword)) {
//            throw new RPanBusinessException("密码信息不正确");
//        }//填入实体信息userLoginContext.setEntity(entity);}

lua脚本,放在resources目录下

-- 判断用户登录的lua脚本local key1 = KEYS[1]
local password1 = ARGV[1]
local password2 = ARGV[2]
-- 阈值
local threshold = ARGV[3]
-- 过期时间
local expiretime = ARGV[4]-- 判断key是否存在
local value = redis.call('get', key1)-- 有key
if value thenif(value >= threshold) thenredis.call('expire', key1, expiretime)  -- 刷新过期时间return -1                               -- 输入密码错误达到threshold次,请1分钟后尝试endif(password1 == password2) then -- 校验正确,删除key并返回1表示通过redis.call('del', key1)return 1elseredis.call('INCR', key1)               -- key的值+1redis.call('expire', key1, expiretime) -- 刷新过期时间return 0                                -- 用户名或密码不正确end
end-- 没有key
if(password1 == password2) thenreturn 1
elseredis.call('setex', key1, expiretime, 1) -- setex key [过期时间] 1return 0   -- 用户名或密码不正确
end

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

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

相关文章

30个商业赚钱的思考(上)

从一名一线技术从业者&#xff0c;到如今技术创业者&#xff0c;不同角色&#xff0c;有了对技术更加深刻的认识和理解。所谓创业、所谓商业&#xff0c;本质就是打通产品、流量和变现的过程。​ 本小节精选30篇商业赚钱思考内容&#xff0c;覆盖商业、认知、营销、管理、创业…

centos7部署zabbix6.4.9

文章目录 [toc]一、环境准备1&#xff09;部署lnmp2&#xff09;修改配置文件3&#xff09;安装数据库 二、部署zabbix1&#xff09;下载zabbix2&#xff09;安装zabbix服务端3&#xff09;修改配置4&#xff09;开机启动5&#xff09;安装客户端 三、登录配置1&#xff09;访问…

在Windows电脑上上传iOS应用至App Store

引言 &#x1f4f1; 使用UniApp开发iOS应用十分便捷&#xff0c;一套代码即可兼容多个平台。然而&#xff0c;UniApp开发iOS应用需要进行证书打包和将IPA文件上传至App Store&#xff0c;这两个步骤通常需要在Mac电脑上完成。那么&#xff0c;如果我们使用的是Windows开发环境…

three.js跟着教程实现VR效果(四)

参照教程&#xff1a;https://juejin.cn/post/6973865268426571784&#xff08;作者&#xff1a;大帅老猿&#xff09; 1.WebGD3D引擎 用three.js &#xff08;1&#xff09;使用立方体6面图 camera放到 立方体的中间 like “回” 让贴图向内翻转 &#xff08;2&#xff09;使…

机器学习 —— 使用机器学习进行情感分析 详细介绍版

机器学习 —— 使用机器学习进行情感分析 详细介绍版 机器学习 —— 使用机器学习进行情感分析 演示版 目录 一、 绪论二、 数据处理1. 构建CSV文档2. 构建模型前的思考2.1. 问题2.2. 解决方法 3. 读取数据4. 用正则表达式来进行对特定符号的剔除5. 使用口袋模型进行文本处理和…

大厂面试:找出数组中第k大的数的最佳算法

一.前置条件 假如数组为a,大小为n&#xff0c;要找到数组a中第k大的数。 二.解决方案 1.使用任意一种排序算法&#xff08;例如快速排序&#xff09;将数组a进行从大到小的排序&#xff0c;则第n-k个数即为答案。 2.构造一个长度为k的数组&#xff0c;将前k个数复制过来并降序…

vscode 配置文件settings.json和c_cpp_properties.json的作用

前言 在 Visual Studio Code (VSCode) 中&#xff0c;settings.json 和 c_cpp_properties.json 都是配置文件&#xff0c;它们分别用于不同的目的。 settings.json settings.json 文件是 VSCode 的用户或工作区设置文件。它允许你自定义 VSCode 的各种行为和外观。 用户设置…

HarmonyOS开发实例:【状态管理】

状态管理 ArkUI开发框架提供了多维度的状态管理机制&#xff0c;和UI相关联的数据&#xff0c;不仅可以在组件内使用&#xff0c;还可以在不同组件层级间传递&#xff0c;比如父子组件之间&#xff0c;爷孙组件之间等&#xff0c;也可以是全局范围内的传递&#xff0c;还可以是…

限流的实现方式

1、tomcat 设置最大链接数 2、Nginx 漏桶算法 3、网关&#xff0c;令牌桶算法

【HTML】简单制作一个3D动态粒子效果的时空隧道

目录 前言 开始 HTML部分 CSS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段HTML&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建两个文本文档&#xff0c;其中HTML的文件名改为[index.html]&#xff0c;CSS的文件名改为[Bab…

单例模式(饿汉模型,懒汉模型)

在着里我们先了解什么是单例模式。 就是某个类在进程中只能有单个实例&#xff0c;这里的单例模式需要一定的编程技巧&#xff0c;做出限制&#xff0c;一旦程序写的有问题&#xff0c;创建了多个实例&#xff0c;编程就会报错。 如果我们学会了单例模式&#xff0c;这种模式…

ubuntu下miniconda安装方式

conda官网&#xff1a; https://docs.anaconda.com/free/miniconda/ 安装方式&#xff1a; 全部执行完毕后&#xff0c;重新登录终端&#xff0c;就可以进入默认的 base 环境。 接下来可以继续使用命令创建和切换所需要的python环境 # 创建python 3.8的环境 mytest conda c…

mineadmin 设置时区

由于不同环境下&#xff0c;会造成时区不一致问题 在/bin/hyperf.php 文件里&#xff0c;设置 date_default_timezone_set(Asia/Shanghai);

qiankun 主子应用使用同一地址同一端口配置

参考官网配置链接&#xff1a;https://qiankun.umijs.org/zh/cookbook#%E5%9C%BA%E6%99%AF-1%E4%B8%BB%E5%BA%94%E7%94%A8%E5%92%8C%E5%BE%AE%E5%BA%94%E7%94%A8%E9%83%A8%E7%BD%B2%E5%88%B0%E5%90%8C%E4%B8%80%E4%B8%AA%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%90%8C%E4%B8%80%E4%B8%A…

【Java网络编程】IP网络协议与TCP、UDP网络传输层协议

1.1、IP协议 当应用层的数据被封装后&#xff0c;想要将数据在网络上传输&#xff0c;数据究竟要被发往何处&#xff0c;又该如何精准的在网络上定位目标机器&#xff0c;此时起到关键作用的就是“IP协议”。IP协议的作用在于把各种数据包准确无误的传递给目标方&#xff0c;其…

微信小程序用户登录授权指定(旧版本)

配置旧版本基础库2.12.3 实现效果 点击登录按钮即可直接登录&#xff0c;获取用户昵称和头像 点击获取头像昵称按钮则需要授权&#xff0c;才能成功登录 代码实现 my.xml <!-- 登录页面,调试基础库为2.20.2库 --> <view class"mylogin"><block w…

B02、分析GC日志-6.3

1、相关GC日志参数 -verbose:gc 输出gc日志信息&#xff0c;默认输出到标准输出-XX:PrintGC 输出GC日志。类似&#xff1a;-verbose:gc-XX:PrintGCDetails 在发生垃圾回收时打印内存回收详细的日志&#xff0c; 并在进程退出时输出当前内存各区域分配情况-XX:PrintGCTimeStamp…

Selenium——基于Web的UI自动化测试工具(一)

一、selenium简介 Selenium是一个自动化测试工具&#xff0c;用于模拟用户在Web上的行为。它支持多种浏览器&#xff0c;如Chrome、Firefox、IE等。Selenium可以实现多种操作&#xff0c;包括打开浏览器、导航到指定URL、填写表单、点击按钮、获取页面元素等。 Seleniu…

简单使用Linux printf 将十进制转换为十六进制

在开发和排查问题过程中&#xff0c;有时我们需要做一些进制的转换&#xff0c;以下是一些快速的小技巧&#xff1a; 下面的是 十进制转换为十六进制&#xff1a; ❯ printf "0x%x\n" 100 0x64 还可以把 十六进制转为十进制&#xff1a; ❯ printf "%d\n&q…

flutter性能优化总结

Flutter应用程序默认已经具有良好的性能&#xff0c;因此您只需要避免常见的陷阱&#xff0c;就可以获得出色的性能。 流畅度(提高渲染性能) 控制build()方法的耗时 避免在 build() 方法中进行重复且耗时的工作&#xff0c;因为当父 widget 重建时&#xff0c;子 Wdiget 的 b…