同一个ip在一小时内不能提交多次

时间:2011-12-02 12:31:46

标签: php ip

我正在尝试创建一个网络调查问卷,但我不希望同一个人使用相同的ip在一小时内提交不止一次,我使用的是php,我假设我需要使用 $_SERVER['REMOTE_ADDR']获取客户端ip并存储在会话或数据库中,然后用它来比较新的ip,我不确定它是否正确,不知道如何在php中实现这一点,任何人都可以请帮助我,提前谢谢!

5 个答案:

答案 0 :(得分:5)

提交调查时:

 /*
   Tracking table structure:
    `id`              INT(11) unsigned NOT NULL AUTO_INCREMENT
    `client_ip`       VARCHAR(15) NOT NULL
    `submitted_time`  DATETIME NOT NULL
 */

 $query = "SELECT count(`id`) AS 'count'
           FROM `tracking_table`
           WHERE 
             `client_ip` = '".mysqli_real_escape_string($link, $_SERVER['REMOTE_ADDR'])."'
             AND `submitted_time` > '".date('Y-m-d H:i:s',strtotime('-1 hour'))."'
           LIMIT 1";
 $result = mysqli_fetch_assoc(mysqli_query($link, $query));

 if ($result['count'] > 0) {
   echo "You have already submitted within the last hour";
   exit;
 }

 // process survey here

 $query = "INSERT INTO `tracking_table`
             (`client_ip`, `submitted_time`)
           VALUES
             ('".mysqli_real_escape_string($link, $_SERVER['REMOTE_ADDR'])."', ".date('Y-m-d H:i:s').")";
 mysqli_query($link, $query);

但是,您可能会发现这不是一个好的要求 - 有许多有效的情况,多个用户可能使用相同的IP地址(例如,学生住宿)。您可能通过强加此限制来阻止有效提交。

修改

以下是您如何使用Cookie执行此操作的基本概要(考虑到下面讨论的限制)。

我们的cookie系统适用于一对值。 ckv_1将保留上次调查提交的时间戳。 ckv_2将根据时间戳和盐来保存哈希值,以阻止人们使用cookie。显然,如果两个cookie都被删除,我们将无法检测到它,但至少这提供了某种验证:

function get_cookie_hash ($timestamp, $salt) {
  return md5("Extra random static string; TS: $timestamp; Salt: $salt; Extra random static string.");
}

$cookieSalt = 'Th1si54rAnd0MsTr1nG!';

// If at least one of the cookies was returned, validate the request
if (!empty($_COOKIE['ckv_1']) || !empty($_COOKIE['ckv_2'])) {

  $valid = FALSE;

  do { // Wrapped in a do-while to allow us to break out easily
    // Make sure both value are set
    if (empty($_COOKIE['ckv_1']) || empty($_COOKIE['ckv_2'])) break;
    // Get old timestamp as integer
    $oldTS = hexdec($_COOKIE['ckv_1']);
    // Make sure timestamp is more than one hour old, and the hash cookie matches it
    if ($oldTS > (time() - 3600) || $_COOKIE['ckv_2'] != get_cookie_hash($oldTS, $cookieSalt)) break;
    // OK if you get here
    $valid = TRUE;
  } while (FALSE);

  if (!$valid) {
    echo "Sorry - you cannot submit a survey more than once in an hour.";
    exit;
  }

}

// process survey here

// Set the tracking cookies after processing (but before any output!)
// We'll set them as HTTP only to help prevent XSS-type attacks
$cookieTime = time();
setcookie('ckv_1', dechex($cookieTime), 7200, '', '', FALSE, TRUE);
setcookie('ckv_2', get_cookie_hash($cookieTime, $cookieSalt), 7200, '', '', FALSE, TRUE);

答案 1 :(得分:0)

使用数据库来存储投票的IP和时间戳,然后在记录投票时(或者更好;当显示调查时告诉用户他已经投票)检查数据库是否是用户的IP($ _SERVER [' REMOTE_ADDR'])已经在数据库中,如果时间戳小于一小时。如果是不允许他投票,否则就行。

答案 2 :(得分:0)

您可以将支票包装在一个类中,然后在您的操作需要该功能时使用它:

class IPChecker
{
    public function storeIP($ip)
    {
        # save $ip with now() and context (if available)
        # in your database
        ...
    }
    public function isBlocked($ip)
    {
        # test if $ip by now() and context (if available)
        # is in your database
        ...
        # return true / false;
    }
}

$ipchecker = new IPChecker();

# on form submit:

$ip = $_SERVER['REMOTE_ADDR'];
if ($ipchecker->isBlocked($ip))
{
    # blocked
    ...
}
else
{
    # good
    $ipchecker->storeIP($ip);
    ...
}

答案 3 :(得分:0)

REMOTE_ADDR确实可以为您提供IP地址。但是:

  • 在许多公司(特别是大公司),传出流量通过代理或防火墙,这使整个公司 - 或至少整个位置 - 看起来来自几个IP地址。一个IP地址可能很容易就是10,000人。
  • 有些ISP使用透明代理来节省带宽。通常,它只对客户端透明,因此整个ISP(或至少区域)将来自多个IP。
  • 手机通常会比每小时更频繁地分配新的IP地址,并且被告知你已经投票了,当你没有时会非常讨厌。
  • IPv6打开了一整套新蠕虫。隐私权扩展旨在打破您正在做的事情。他们会的。

因此,这里有一个更准确的REMOTE_ADDR描述:一个地址,作为完整TCP会话地址(服务器,服务器端口,远程地址,远程端口)的一部分,允许您发送一部分数据包所述会议。它可能是也可能不是实际客户的地址(通常不是),可能会或可能不会与请求请求匹配,并且可能会或可能不会被许多其他人共享。

答案 4 :(得分:0)

$_SERVER['REMOTE_ADDR']存储在数据库表中,并附上上次提交调查的时间戳。该表可能有两列,如IPAddress(varchar 100), TimeStamp(int)。并在PHP代码

<?php
     //query the $_SERVER['REMOTE_ADDR'] in database and get timestamp, if found compare it with current time stamp, difference should be greater than an hour

if($diff > 3600)
{
   print "You are not allowed to post your survey more than once in an hour"
   exit;
}

//Your page code
?>