-1
我正在实现一个块登录,所以如果发生很多(10?)登录失败(如有人试图强制密码),帐户无法尝试登录几分钟(即使使用有效的密码) ...如何限制使用redis的登录尝试?
我虽然速率限制使用Redis的图案,并在redis.io他们提供了两种可能的实现:
但是他们给的问题双方,尤其是在并发或丢失命令的情况下。
你推荐什么解决方案?
我正在实现一个块登录,所以如果发生很多(10?)登录失败(如有人试图强制密码),帐户无法尝试登录几分钟(即使使用有效的密码) ...如何限制使用redis的登录尝试?
我虽然速率限制使用Redis的图案,并在redis.io他们提供了两种可能的实现:
但是他们给的问题双方,尤其是在并发或丢失命令的情况下。
你推荐什么解决方案?
我找到了一个可能的解决方案。这是伪代码:
FUNCTION LIMIT_API_CALL(key):
value = INCR(key)
IF value > 10 THEN
ERROR "too many requests"
ELSE
EXPIRE(key, blockedTime)
PERFORM_API_CALL()
END
这似乎相比redis.io链接实现小幅转移问题,但我认为这是稳健的规定的问题,所以不存在内存泄漏,以及即使其中一个命令失败,TTL也会始终设置。
EDIT(一年后):
这一招已经部署在生产,具有以下除了解决第一个注释检测到的问题:
PERFORM_API_CALL的成功返回删除密钥,重置到期计数器:
FUNCTION LIMIT_API_CALL(key):
value = INCR(key)
IF value > 10 THEN
ERROR "too many requests"
ELSE
IF (PERFORM_API_CALL())
DEL(key)
ELSE
EXPIRE(key, blockedTime)
END
这似乎是一个很好的简单快速的代码。我认为它可能会遇到一些与竞争条件或编码缺陷无关的问题。例如,如果您只想允许“每小时登录10次”,但用户每30分钟只尝试登录一次,在5小时内他们将被拒绝登录尝试另一整小时 - 这种行为更像是“在拒绝服务之前,每小时登录2次“。另一种情况:从第一次登录尝试到第九次,几乎一个小时过去了,但用户仍然只能在整个下一个小时再尝试一次。 – ChisholmKyle
你当然是对的。然而,通过这个非常简单的技巧检测并解决了这个问题:成功登录后,密钥被移除(并且重置失败),因此只有失败才会触发增加的到期计数器。这允许攻击者尝试更多的组合,只要他知道什么时候会成功登录就会发生,但是对于每个到期单元的每次成功登录,他只能将速率提高一倍......这在现实世界中不会发生太多事情。 – Daren