один и тот же ip не может подать более одного раза в течение часа - PullRequest
1 голос
/ 02 декабря 2011

Я пытаюсь создать анкету для веб-опроса, но я не хочу, чтобы одни и те же люди, использующие один и тот же ip, отправляли его более одного раза в течение часа, я использую php, я предполагаю, что мне нужно использовать $_SERVER['REMOTE_ADDR'] чтобы получить ip клиента и сохранить его в сеансе или базе данных, а затем использовать его для сравнения нового ip, я не уверен, что это правильно, и не знаю, как точно реализовать это в php, может кто-нибудь мне помочь с этим, спасибо заранее!

Ответы [ 5 ]

5 голосов
/ 02 декабря 2011

Когда опрос представлен:

 /*
   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-адрес (например, например, для проживания студентов). Вы можете запретить действительные представления, установив этот лимит.

EDIT

Вот основная схема того, как вы можете сделать это с помощью файлов cookie (с учетом ограничений, обсуждаемых ниже).

Наша система cookie работает с парой значений. ckv_1 будет содержать временную метку, в которую был отправлен последний опрос. ckv_2 будет содержать хэш, основанный на метке времени и соли, чтобы не дать людям испортить куки. Очевидно, что если оба куки будут удалены, мы не сможем их обнаружить, но, по крайней мере, это обеспечивает своего рода проверку:

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);
0 голосов
/ 02 декабря 2011

Сохраните $_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
?>
0 голосов
/ 02 декабря 2011

REMOTE_ADDR действительно дает вам IP-адрес.Но:

  • Во многих компаниях (особенно крупных) исходящий трафик проходит через прокси-серверы или брандмауэры, что делает всю компанию - или, по крайней мере, всю локацию - полученной с нескольких IP-адресов.Один IP-адрес может легко составить 10000 человек.
  • Некоторые интернет-провайдеры используют прозрачное проксирование для экономии пропускной способности.Часто он прозрачен только для клиента , поэтому весь провайдер (или хотя бы регион) будет приходить с нескольких IP-адресов.
  • Сотовым телефонам часто назначаются новые IP-адреса чаще, чем каждый часи если вам скажут, что вы уже проголосовали, когда у вас его нет, это будет довольно неприятно.
  • IPv6 открывает совершенно новую банку червей.Расширения конфиденциальности предназначены, чтобы сломать то, что вы делаете.Они будут.

Итак, вот более точное описание REMOTE_ADDR: адрес, который как часть полного адреса сеанса TCP (сервер, порт сервера, удаленный адрес, удаленный порт) позволяетВы отправляете пакет, который является частью указанного сеанса.Это может быть или не быть адрес реального клиента (обычно это не так), может совпадать или не совпадать с запросом к запросу, и может или не может быть общим для многих других людей.

0 голосов
/ 02 декабря 2011

Вы можете свернуть свои чеки в классе, а затем использовать его, когда ваши действия требуют функциональности:

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);
    ...
}
0 голосов
/ 02 декабря 2011

Используйте базу данных для хранения IP-адресов и временных отметок голосов, а затем при записи голосования (или еще лучше; при отображении опроса, чтобы вы сказали пользователю, что он уже проголосовал) проверьте базу данных, если IP-адрес пользователя ($ _SERVER [' REMOTE_ADDR ']) уже находится в БД, и если временная метка моложе одного часа. Если это не позволяет ему голосовать, в противном случае сделайте.

...