任何人都可以在 ajax 聊天中使用简单的 for 循环,并让聊天有时发送 1000 条消息。在我的 ajax 聊天中,每条消息都存储有日期、时间(时间戳)。
我需要找到一种方法来防止这个问题,我想过一个,但我不知道我该怎么做:
按邮寄时间防止垃圾邮件
基本上选择 5 条消息,它们的日期、时间显示不到 10 秒(一起)。如果这些消息一并在 10 秒内发布,则在几秒钟内阻止用户聊天。
但我真的不认为这可以工作,也不知道如何做到这一点。
有没有类似的,或更好的解决方案,或如何做的提示?
任何人都可以在 ajax 聊天中使用简单的 for 循环,并让聊天有时发送 1000 条消息。在我的 ajax 聊天中,每条消息都存储有日期、时间(时间戳)。
我需要找到一种方法来防止这个问题,我想过一个,但我不知道我该怎么做:
按邮寄时间防止垃圾邮件
基本上选择 5 条消息,它们的日期、时间显示不到 10 秒(一起)。如果这些消息一并在 10 秒内发布,则在几秒钟内阻止用户聊天。
但我真的不认为这可以工作,也不知道如何做到这一点。
有没有类似的,或更好的解决方案,或如何做的提示?
编辑:如果您有可用的数据库资源,DanFromGermany 发布的解决方案是一个好方法。如果DB是瓶颈,可以切换到以下方法:
你有一个对 phpfile 的 AJAX 调用,比如说 process.php。在 process.php 中你开始一个会话,并开始一个值 $_SESSION['lastChatMessage']=0;
然后你做一个 if/else arround 实际代码:
// time based check:
if($_SESSION['lastChatMessage'] > time()-1 ){ echo "Only one post per second";}
else{
// some code you use now
$_SESSION['lastChatMessage'] = time();// save time of posting
}
您还可以创建一个 $lastChatMessage 数组并记住其中的每次。然后创建一个删除所有小于 time()-$diffYouWant 的值的函数。将保留许多帖子,这取决于您希望该数字有多大:)
if(count( $_SESSION['lastChatMessage']) > $maxPostsAllowed){ echo 'No flooding please';}
else{
// your code
}
在服务器即将保存聊天消息的脚本部分中,您连接了一个数据库查询,例如
SELECT COUNT(*)
FROM chat_messages
WHERE uid='1234' AND timestamp > DATE_SUB(NOW(), INTERVAL 10 SECOND)
LIMIT 10
然后检查结果是否大于您的限制并返回 false,或者消息“在太短的时间内发送的消息太多”
另一种可能更好的方法是不仅要识别用户/会话,还要保存 IP 并将消息限制到 IP。许多现代机器人可以轻松绕过会话或非常快速地切换 IP,因此您应该选择一种以上技术的组合。
还要考虑客户端预防,例如散列消息,或向消息添加校验和。许多机器人不会说 JavaScript 太好。
你想在服务器端控制它,正如其他评论中提到的那样,你的垃圾邮件发送者可能知道足够多的 JavaScript 来删除任何保护。
使用 PHP 和 MySQL,这里有一个建议:
// check if the user is spamming
$r_antispam = mysqli_query($db, "SELECT `date` FROM `the_messages` WHERE `id_conversation`=111 AND `id_exp`=222 AND `date` >= DATE_SUB(NOW(), INTERVAL 10 SECOND) LIMIT 8");
if(mysqli_num_rows($r_antispam) == 8)
{ echo 'spam'; exit(); }
当然,您可能想要调整其中允许的延迟和最大消息数。
现在,在您的 Ajax 请求中,您可以这样使用 Ajax 文件返回的“垃圾邮件”一词:
$.post("ajax/messages-post.php", {
id_conv: 111,
message: message_text
}).
done(function(e)
{
if(e == 'spam')
{
alert('do not spam, please...');
}
else
{
// your message is posted, you can display it
}
}).
fail(function() { console.log('error'); });
在您的 JavaScript 中,如果您在将其值发布到 Ajax 文件之前清空用户编写消息的 textarea,因为该消息不会记录在数据库中,您可以将其重新插入到 textarea 中,以防万一。不是垃圾邮件...