这是我参与「第五届青训营」笔记创作活动的第7天
在客户端没有支持二步验证(如手机验证码)的情况,为了进一步保护用户,提高安全性,实现了十分钟内连续尝试登录5次失败,需要等待30分钟才能登录的逻辑,减少攻击者能尝试的次数,具体流程如下:
具体来说就是
-
登录请求
-
验证锁定缓存,锁定直接返回登录次数过多已锁定
-
未锁定 验证账号密码
-
验证失败 最近10分钟失败次数计数 次数>=5,设置锁定缓存,返回失败
-
验证成功 删除计数缓存,返回成功
要注意的时间滑动的问题,,比如10分钟内只失败了4次 然后又可以进行请求了,又来了一次验证失败的请求,这个请求与前面的后三次失败也在10分钟内,但是这时候失败总次数只是1,其实相对于最新的一次登录失败,十分钟内的失败次数也是4。 是每次都是最近10分钟的总失败次数,而不是失败了一次开始10分钟过期做自增。
解决思路
每分钟的操作失败进行单独的统计,每次用系统时间向前检查10分钟总共失败次数,大于5就进行锁定,做到了
然后
-
登录失败计数器的key设计为:一串字符串 + 用户名(假设具有唯一性)+ 登录失败的时间
-
锁定登录操作的key设计为:一串字符串 + 用户名(假设具有唯一性)
然后还可以用令牌桶来实现。 具体原理是
接口限制 t 秒内最大访问次数为 n,则每隔 t/n 秒会放一个 token 到桶中;
桶中最多可以存放 b 个 token,如果 token 到达时令牌桶已经满了,那么这个 token 会被丢弃;
接口请求会先从令牌桶中取 token,拿到 token 则处理接口请求,拿不到 token 则执行限流。
匀速生成令牌,直到达到桶的最大值,每来个请求就拿走一个,拿不到的就舍弃。