首页 > 其他分享 >简易首页防暴力-字典计时器

简易首页防暴力-字典计时器

时间:2024-05-16 15:42:13浏览次数:18  
标签:username string dateTime DateTime 计时器 首页 lockoutTimes 字典

       有时候首页需要限制下相同账号的错误登录次数,防止暴力破解,实际而言,还是有一点点作用,虽然并不是很大,一定层度上也能扼杀一番,主要是调整起来方便,对于老旧系统改造起来比较快,核心是字典,一个记录失败次数,一个记录账号解锁的时间,在账号登录时先去字典里面校验,不用频繁的请求数据库.  需要注意的是,这个字典要设置为全局。否则切换客服端就会失效.

        //次数字典
        private static Dictionary<string, int> errorCounts = new Dictionary<string, int>();
        //时间字典
        private static Dictionary<string, DateTime> lockoutTimes = new Dictionary<string, DateTime>();

字典设置完毕,接下来就是在登录的时机点上校验次数,基本思路是,每个登录进来的账号无论密码,先加到字典中,设置一个初始时间,后边后续统一判断

        public ActionResult ICCLogin(string userName, string password)
        {
            int result;
            DateTime dateTime;
            //先加时间字典
            if (!errorCounts.TryGetValue(userName, out result))
            {
                errorCounts[userName] = 0;
                lockoutTimes[userName] = DateTime.MinValue;
            }
            //判断次数字典
            if (IsLockedOut(userName, out dateTime))
            {
                // 计算两个日期时间之间的时间间隔
                TimeSpan timeDifference = dateTime.Subtract(DateTime.Now);
                // 计算总分钟数并向上取整
                int totalMinutes = (int)Math.Ceiling(timeDifference.TotalMinutes);
                // 如果向上取整后的分钟数小于1,设为30
                if (totalMinutes == 1)
                {
                    totalMinutes = 30;
                }
                string suf = totalMinutes == 30 ? "s" : "分钟";
                LibExceptionManagent.ThrowErr(string.Format("验证失败次数过多,账户已被锁定,{0}{1}后重试", totalMinutes, suf));
                return View();
            }

次数字典方法

        private bool IsLockedAccount(string username, out DateTime dateTime)
        {
            //先加次数字典
            if (!lockoutTimes.ContainsKey(username))
            {
                lockoutTimes[username] = DateTime.MinValue;
            }
            //获取当前账号的可放开时间
            dateTime = lockoutTimes[username];
            return lockoutTimes[username] > DateTime.Now;
        }

贸然看去,貌似没啥子问题, 实际上还缺少一个归零的操作,到达账号解封时间后, 需要置空错误次数,否则就会无限循环,5分钟结束后又从头开始

        private bool IsLockedOut(string username, out DateTime dateTime)
        {
            //先加次数字典
            if (!lockoutTimes.ContainsKey(username))
            {
                lockoutTimes[username] = DateTime.MinValue;
            }

            dateTime = lockoutTimes[username];
            bool bol = lockoutTimes[username] > DateTime.Now;
            //获取当前账号的可放开时间
            if (bol && errorCounts.TryGetValue(username, out _))
            {
                errorCounts[username] = 0;
            }
            return bol;
        }

如此基本上满足次数校验,为了形成一个小小的闭环,全局静态字典需要回收,再写一个定时任务清空字典,避免字典值越来越大

        private static readonly Timer timer = new Timer(ClearDictionary, null, TimeSpan.Zero, TimeSpan.FromMinutes(5));

        private static void ClearDictionary(object state)
        {
            // 在定时器触发时清空字典
            List<string> keysToRemove = lockoutTimes.Where(pair => pair.Value != DateTime.MinValue && pair.Value <= DateTime.Now).Select(pair => pair.Key).ToList();
            foreach (string key in keysToRemove)
            {
                lockoutTimes.Remove(key);
                if (errorCounts.TryGetValue(key, out int count))
                {
                    errorCounts.Remove(key);
                }
            }
        }

 

ok , 搞定

 

标签:username,string,dateTime,DateTime,计时器,首页,lockoutTimes,字典
From: https://www.cnblogs.com/Sientuo/p/18196047

相关文章

  • Python闭包函数和计时器
    闭包函数闭包的内部函数中,对外部作用域的变量进行引用闭包无法修改外部函数的局部变量闭包可以保存当前的运行环境#普通方法实现defoutput_student(name,gender,grade=1):print(F"新学期开学啦,学生{name}是{gender},他是{grade}年级学生")output_student('李白'......
  • Python中如何避免字典和元组的多重嵌套的方法
    一、字典、元组的多重嵌套例1:记录全班学生的成绩。分析:定义一个SimpleGradebook类,学生名是字典self._grades的键,成绩是字典self._grades的值。classSimpleGradebook():def__init__(self):self._grades={}defadd_student(self,name):self.......
  • 字符串、列表、字典内置方法
    字符串内置方法【一】字符串的查找字符串内部的字符默认从左向右找,并返回当前字符在串中的索引坐标【1】find方法name='qwerooehjkl'print(name.find('e'))默认只找一次,找到就不找了#2第二个e不找了可以指定寻找的区间,参数不带''引号从第三个到最后一个pr......
  • ABC353E字典树处理最长公共前缀
    https://atcoder.jp/contests/abc353/tasks/abc353_e其实就是字典树板子题。似乎遇到最长公共前缀,就该想到字典树。依次加入每个字符串:维护一个数组siz来统计在当前串之前的串在对应点的出现次数。手模一下字典树的建树过程,显然如果当前串\(S_i\)能跑到一个曾经串\(S_......
  • Python-有序字典OrderedDict练习题
    问题:读取键盘输入结果,创建n个键值对,将其排序后放入有序字典并输出。详细描述:根据提示,实现函数功能:读取n(n>0)行输入,以每一行的数据为key,行号(从0开始)为value,建立n对键值对,然后将他们按照key排序后,放入一个有序字典,最后输出这个有序字典。importcollectionsdefFunc():pairs......
  • 一篇文章掌握Python中多种表达式的使用:算术表达式、字符串表达式、列表推导式、字典推
    Python中的表达式可以包含各种元素,如变量、常量、运算符、函数调用等。以下是Python表达式的一些分类及其详细例子:1.算术表达式算术表达式涉及基本的数学运算,如加、减、乘、除等。#加法表达式sum=3+5#结果为8#乘法表达式product=4*6#结果为24#复......
  • P4407 [JSOI2009] 电子字典
    题目链接:https://www.luogu.com.cn/problem/P4407trie树+爆搜做法:对所有文本串建树。对于编辑距离要求的三种情况,分四类在trie树上爆搜即可。#definemaxn200010structtrie{intson[maxn][26];intcnt[maxn];intidx=0;map<string,bool>mm;intv......
  • Python中级之数据类型的内置方法2(字典和列表)
    【一】字符串类型的内置方法(熟悉)【1】查找(1)find方法#【1】默认从左到右开始查找,找得到则返回元素所在的索引位置name='ligo'str=name.find('i')print(str)#输出1#【2】也可在区间内寻找,找不到则返回-1str=name.find('g',3,4)print(str)#输出-1#【3】也......
  • unity+计时器,随时开启
    //定义定时器容器Dictionary<string,WaitForSecondsRealtime>RealtimeDict=newDictionary<string,WaitForSecondsRealtime>();//剩余时长privatefloattimeRemaining;//开始计时publicvoidStartTimer(floatduration){......
  • python3.2:字典
    字典相比较列表,优势:查找key的需求,列表需要遍历,字典查找速度很快,很方便,定义 特性查找、增加和修改操作 删除操作循环操作 全局函数 ......