我需要为 Web 服务实现登录速度检查。服务是ruby,数据库是MySql。
我可以想象出执行此操作的糟糕方法。例如,有一个表存储每次登录尝试的时间以及是否成功,每次用户尝试登录时,查询该表以获取最后的 n 次登录尝试并运行一些简单的针对它的算法。不过,这显然非常低效。每次登录尝试都会在一个相当大的表上进行选择和插入,这会降低整个系统的速度。
更好的方法可能是说 n 的值被硬编码为 3 或其他值,然后在用户表中(存储密码验证程序的任何地方)添加 n 列,其中包含最近的 n 次登录尝试。这删除了额外的选择语句,并且用户表可能比登录尝试表短得多。但是,它会丢失大量数据,如果更改算法,这些数据可能会很有趣。
在这一点上,我倾向于该结构的变体,它在表中放置一个带有密码验证器的文本字段,并且该文本字段包含一个序列化对象,该对象是登录尝试记录的数组。在登录尝试时,该字段将被解析和重写。这解决了固定的 n 问题,同时避免了查询非常大的表。然而,从数据库中读取文本字段当然具有较差的磁盘访问特性,这可能最终也使其成为一个糟糕的解决方案。
最后,另一种可能性是使用 MySql 的日志文件支持的数据库(我不知道是谁的名字),但我对此几乎一无所知,除了它在查询日志文件方面应该是高效的。
我对 Stack Overflow 的问题是:行业中通常如何实现登录速度检查?
更新 1:
我应该定义速度检查。登录尝试的速度检查跟踪连续失败的次数和连续失败发生的时间范围。第一个回复确实指向具有这些属性的解决方案。不过,我想知道它是否保留了足够的信息以允许在速度检查中具有灵 active 。我从未构建过这样的系统,我担心我忽略了速度检查的重要方面,我希望在开始构建它时考虑这些方面......
最佳答案
最后,我构建了类似于 John Boker 建议的东西。用于对用户进行身份验证的表有两个新列——failed_login_count
和 first_failed_login
,这是一个 DateTime 对象。每次用户成功登录时,failed_login_count
重置为 0,first_failed_login
重置为 null
(如果它们尚未登录)。每次登录尝试失败时,failed_login_count
都会增加。如果它是 0,first_failed_login
获取当前时间。每次用户尝试登录时,都会在验证密码之前进行速度检查。如果 failed_login_count
大于 0,则除以当前时间与 first_failed_login
之间的时间差。如果该值大于最大允许速度,则速度检查失败。
此外,我积极记录失败的登录尝试和失败的速度检查以供将来离线处理,这样我就可以跟踪暴力破解帐户的尝试并禁用登录尝试失败次数过多的帐户,而无需跟踪这些计算所需的详细信息在数据库本身。
关于mysql - 实现登录速度检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/831618/