组队大项目--用户尝试登录次数限制 | 青训营笔记

153 阅读2分钟

这是我参与「第五届青训营」笔记创作活动的第7天

在客户端没有支持二步验证(如手机验证码)的情况,为了进一步保护用户,提高安全性,实现了十分钟内连续尝试登录5次失败,需要等待30分钟才能登录的逻辑,减少攻击者能尝试的次数,具体流程如下:

image.png

具体来说就是

  1. 登录请求

  2. 验证锁定缓存,锁定直接返回登录次数过多已锁定

  3. 未锁定 验证账号密码

  4. 验证失败 最近10分钟失败次数计数 次数>=5,设置锁定缓存,返回失败

  5. 验证成功 删除计数缓存,返回成功

要注意的时间滑动的问题,,比如10分钟内只失败了4次 然后又可以进行请求了,又来了一次验证失败的请求,这个请求与前面的后三次失败也在10分钟内,但是这时候失败总次数只是1,其实相对于最新的一次登录失败,十分钟内的失败次数也是4。 是每次都是最近10分钟的总失败次数,而不是失败了一次开始10分钟过期做自增。

解决思路

每分钟的操作失败进行单独的统计,每次用系统时间向前检查10分钟总共失败次数,大于5就进行锁定,做到了

然后

  • 登录失败计数器的key设计为:一串字符串 + 用户名(假设具有唯一性)+ 登录失败的时间

  • 锁定登录操作的key设计为:一串字符串 + 用户名(假设具有唯一性)

然后还可以用令牌桶来实现。 具体原理是

接口限制 t 秒内最大访问次数为 n,则每隔 t/n 秒会放一个 token 到桶中;

桶中最多可以存放 b 个 token,如果 token 到达时令牌桶已经满了,那么这个 token 会被丢弃;

接口请求会先从令牌桶中取 token,拿到 token 则处理接口请求,拿不到 token 则执行限流。

匀速生成令牌,直到达到桶的最大值,每来个请求就拿走一个,拿不到的就舍弃。