我正在尝试用基于redis的实现替换Drupal 8的防洪服务的sql实现.
请参阅https://github.com/drupal/drupal/blob/8.0.x/core/lib/Drupal/Core/Flood/DatabaseBackend.php
要求是这样的:
每次出现的动作/事件(例如,尝试登录)都会记录到期,标识符和时间戳
我需要能够防止某个动作在给定的时间范围内完成N次以上
我希望能够清理过期的事件
在10分钟内阈值为3的情况下,如果用户尝试一次,然后在5分钟后尝试两次,则他被阻止并且可以在5分钟后再次尝试一次.不是10.虽然第二种方法是一种有效的方法,但不是sql实现的工作方式或测试期望它如何工作.
正如您在API中看到的那样,我也不知道在注册事件时阈值是什么,我只知道单个事件的到期时间.
我对如何实现这个的想法:
如果在N次出现之后应该锁定给定时间,那么使用单个KEY for event会很容易:增加的标识符,一旦达到最大值,它将被锁定直到它再次到期并且每个INCR也会更新到期(或不到期).
我发现很多帖子询问列表条目的到期,这是不可能的.有使用排序集的变通方法和按范围删除.大多数似乎使用单个全局集,但我不能轻易计算我的事件+标识符 - 我想.
写完所有这些之后,我可能真的知道它是如何工作的,所以我想我正在寻找的是关于这是否有意义或者是否有更简单的方法的反馈.
每个事件:标识符组合是一个键,包含一个有序集.它使用到期作为分数,并将值用作唯一值,可能是以微秒为单位的创建时间.我计算未过期的记录以检测是否达到阈值.我正在更新每个事件的到期时间:标识符到提供的到期时间窗口,因此除非给定的标识符/客户端不放弃并继续尝试,否则它将被自动删除,而不会达到过期时间.是否值得清理集合中的记录,例如在进行新的注册时?它看起来相当快,我有时也只能这样做.