【问题标题】:AJAX chat - Prevent spam server sided?AJAX 聊天 - 防止垃圾邮件服务器端?
【发布时间】:2013-06-25 14:31:34
【问题描述】:

任何人都可以在 ajax 聊天中使用简单的 for 循环,并让聊天有时发送 1000 条消息。 在我的 ajax 聊天中,每条消息都存储有日期、时间(时间戳)。

我需要找到一种方法来防止这个问题,我已经想到了一个,但我不确定我该怎么做:

按发布时间阻止垃圾邮件

基本上选择 5 条消息,它们的日期、时间显示不到 10 秒(一起)。 如果这些消息一并在 10 秒内发布,则会在几秒钟内阻止用户聊天。

但我真的认为这行不通,也不知道该怎么做。

有没有类似的,或更好的解决方案,或提示?

【问题讨论】:

  • 为什么它不起作用?在某个时间范围内计算最后 X 条消息对我来说似乎是一个非常合理的解决方案。
  • 可以,但是如何在特定时间内选择项目?
  • 您说您为每条消息存储了时间戳,因此只需使用查询来提取过去 X 秒内的消息数。

标签: php


【解决方案1】:

编辑:如果您有可用的数据库资源,DanFromGermany 发布的解决方案是一个好方法。如果DB是瓶颈,可以改用以下方法:

你有一个对 php 文件的 AJAX 调用,比如说 process.php。在 process.php 中你开始一个会话,并开始一个值 $_SESSION['lastChatMessage']=0;

然后你在实际代码周围做一个 if/else:

// 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
}

【讨论】:

  • 我同意这一点。查询数据库以防止垃圾邮件是一个非常糟糕的决定。
【解决方案2】:

在你的脚本部分,服务器将要保存聊天消息的地方,你连接了一个数据库查询,比如

SELECT COUNT(*)
FROM chat_messages
WHERE uid='1234' AND timestamp > DATE_SUB(NOW(), INTERVAL 10 SECOND)
LIMIT 10

然后检查结果是否大于你的限制并返回false,或者一条消息“在太短的时间内发送的消息太多”

另一种可能更好的方法是不仅识别用户/会话,还保存 IP 并将消息限制到 IP。许多现代机器人可以轻松绕过会话或快速切换 IP,因此您应该使用多种技术的组合。

还要考虑客户端预防,例如散列消息,或向消息添加校验和。许多机器人不太擅长 JavaScript。

【讨论】:

  • 是的。你有一个列来识别用户/会话,不是吗?
  • “许多机器人不会说 JavaScript 太好。”我一直认为,如果有人在弄乱我的 AJAX 脚本,他们已经达到了 javascript 操作级别。保存总比后悔好
  • "ajax scripts" 只是一个由 HTTP 请求调用的 URL。不需要Javascript。如果您在通过客户端/服务器协商生成的消息中添加签名,那么它不仅仅是从您的 js/firebug 控制台复制的 HTTP 请求
【解决方案3】:

您希望在服务器端控制它,正如在其他 cmets 中提到的那样,您的垃圾邮件发送者可能知道足够的 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 以防万一这不是垃圾邮件...

【讨论】:

    猜你喜欢
    • 2012-07-21
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多