PHP:一种存储登录尝试次数的方法?

PHP:一种存储登录尝试次数的方法?,php,mysql,sql,security,Php,Mysql,Sql,Security,我想阻止所有的请求,比如说,10分钟,通过IP,如果在任何5分钟的间隔内有5个错误。 我正在考虑一种存储这些数据的方式,这种方式对性能的影响最小 特别是关于如何设计数据库表和存储数据 如果我为IP制作一个固定表作为主表,例如使用mysql: ip int(10) unsigned, primary key (ip) attempts int(5), lastaccess timestamp default current_timestamp 那么它将不充分地积累尝试 另一方面,如果我用时间戳记

我想阻止所有的请求,比如说,10分钟,通过IP,如果在任何5分钟的间隔内有5个错误。 我正在考虑一种存储这些数据的方式,这种方式对性能的影响最小

特别是关于如何设计数据库表和存储数据

如果我为IP制作一个固定表作为主表,例如使用mysql:

ip int(10) unsigned, primary key (ip)
attempts int(5),
lastaccess timestamp default current_timestamp
那么它将不充分地积累尝试

另一方面,如果我用时间戳记录所有不正确的尝试,例如:

ip int(10) unsigned,
lastaccess timestamp default current_timestamp,
primary key (ip,lastaccess)
然后在5分钟的时间间隔内倒计时,表格可能会随着所有这些数据而变得非常庞大,并使系统速度变慢。。。它还需要维护


那么,你能给我一些更方便的建议吗?…

我会存储IP地址和最近x次尝试的时间戳。在数据库、memcached类型的存储中,或者可能只是一些平面文件中,这取决于您预期的流量

如果是一个数据库,您可以轻松地查询类似于
COUNT(timestamps)GROUP BY ip WHERE timestamp[在过去5分钟内]
之类的内容,并偶尔使用一个简单的
删除WHERE timestamp[在5分钟前]
来清理数据库。清理可能发生在cron作业中,也可能发生在垃圾收集类系统中的每个x请求中


如果是memcached或平面文件,则将时间戳存储在FIFO数组中,即一个简单的
数组(123456…,123456…,…)
,不断截断。

我将存储IP地址和最后x次尝试的时间戳。在数据库、memcached类型的存储中,或者可能只是一些平面文件中,这取决于您预期的流量

如果是一个数据库,您可以轻松地查询类似于
COUNT(timestamps)GROUP BY ip WHERE timestamp[在过去5分钟内]
之类的内容,并偶尔使用一个简单的
删除WHERE timestamp[在5分钟前]
来清理数据库。清理可能发生在cron作业中,也可能发生在垃圾收集类系统中的每个x请求中


如果是memcached或平面文件,则将时间戳存储在FIFO数组中,即一个简单的
数组(123456…,123456…,…)
,不断截断。

试试看。我建议您使用
redis
以防您非常担心
所有这些数据可能会使表变得非常庞大

为每个用户生成一个唯一的ID(最可能是IP,但是考虑来自同一个网络的用户。对于EX:来自组织的用户将具有与来自所有机器的所有输出请求相关的相同IP),并使用带有Unique ID的键值和值作为计数器[数据存储尝试次数]的数据类型。 来自文档的

字符串的一个用例

使用INCR系列中的命令将字符串用作原子计数器: 增加,减少,增加

字符串数据类型也支持过期。因此,您生成的所有密钥将有5分钟的到期时间,一旦达到时间限制,这些密钥将自毁。您只需读取计数器值即可确定是否阻止用户。现在,随着时间的推移,您不必担心记录的数量


Redis将所有数据存储在内存中。我想您也可以获得一些性能改进

试试看。我建议您使用
redis
以防您非常担心
所有这些数据可能会使表变得非常庞大

为每个用户生成一个唯一的ID(最可能是IP,但是考虑来自同一个网络的用户。对于EX:来自组织的用户将具有与来自所有机器的所有输出请求相关的相同IP),并使用带有Unique ID的键值和值作为计数器[数据存储尝试次数]的数据类型。 来自文档的

字符串的一个用例

使用INCR系列中的命令将字符串用作原子计数器: 增加,减少,增加

字符串数据类型也支持过期。因此,您生成的所有密钥将有5分钟的到期时间,一旦达到时间限制,这些密钥将自毁。您只需读取计数器值即可确定是否阻止用户。现在,随着时间的推移,您不必担心记录的数量



Redis将所有数据存储在内存中。我认为您可能也会获得一些性能改进

将它们存储在会话变量中如何?是的,如果客户端阻止cookies怎么办?@rsplak任何试图强行登录的人都会放弃会话cookies。您可能可以检查客户端的IP。虽然IP不是唯一标识符(NAT’ed客户端可以具有相同的IP),但这是阻止可能的暴力登录的一种可能的方法。为什么不运行cron脚本,在每天结束时清空表?将它们存储在会话变量中如何?是的,如果客户端阻止Cookie怎么办?@rsplak任何试图强行登录的人都将丢弃会话Cookie。您可能可以检查客户端的IP。虽然IP不是唯一标识符(NAT’ed客户端可以具有相同的IP),这是阻止可能的暴力登录的一种可能的方法。为什么不在每天结束时运行一个清空表的cron脚本呢?这是我遇到问题时所做的,它起了作用:)没有看到任何显著的性能影响,因为大多数用户在mostWell尝试两次后立即获得密码,但它也有一个缺点——维护。不管成功与否,我都会比存储最后的X次尝试更进一步。如果您需要,存储所有登录尝试是一个有用的审计工具,并为您提供一些分析。当尝试失败时,您仍然可以在一段时间内查询失败的尝试,并使用IP禁止的辅助表。@Anon您是指偶尔的
DELETE
查询吗?我不认为这是现实世界的问题。此外,Leigh还提出了一个很好的观点,即根本不要删除尝试