Хотелось бы получить отзывы о моем программировании на PHP и советы по сессиям - PullRequest
0 голосов
/ 13 августа 2010

Привет, я новичок в PHP, поэтому очень хотел бы, чтобы вы поняли, как я программирую, а также у меня возникли проблемы с решением проблемы с сессией.

Я делаю скрипт для бартерной и Локальной торговой системы ( LETS ), и в настоящее время я кодирую страницу предложения, где пользователь может просмотреть все предлагаемые товары / услуги и затем нажать на продукт / услуга, чтобы получить более подробную информацию. После нажатия на товар / услугу они могут сделать ставку. В системе LETS участники имеют Доллары времени / жизни, которые они могут заработать, торгуя с другими людьми. Так что в значительной степени это его альтернативная валюта, которая создается из людей, выполняющих работу (в отличие от нашей нынешней системы фиатных валют, которую используют правительства). Поэтому, если у пользователя есть Life Dollars, он может сделать ставку другому пользователю, который предлагает свои товары / услуги.

Я делаю все это на одной странице PHP, которая называется offers.php. Проще говоря, будет 4 страницы, сделанные из offers.php. Когда пользователь сначала просматривает раздел предложений (offers.php), он видит все предложения, затем он может щелкнуть предложение (offers.php?id=X), а затем щелкнуть, чтобы сделать ставку (offers.php?id=X&action=makebid), а затем подтвердить ставку (offers.php?id=X&action=confirm).

Хорошо, поэтому проблема с моими Сессиями такова: Сессии работают, когда пользователь начинает с offers.php?id=X до конца. Если они пойдут по тому пути, к которому, как они полагают, проблем быть не должно, они не смогут обойти мою проверку. Однако, если пользователь нажимает, скажем, offers.php?id=100, а затем вводит URL offers.php?id=200&confirm в адресную строку браузера, он может пропустить мою проверку, в результате чего предложение будет введено дважды (если они уже сделали предложение). То же самое происходит, когда пользователь переходит непосредственно на другой offers.php?etc URL, но это не составляет большой проблемы. Я все еще хотел бы исправить это, потому что я обеспокоен тем, когда страница продукта / услуги вставляется на другой веб-сайт, потому что тогда сеансы не будут работать должным образом. Имеет ли смысл то, что я говорю? Я могу объяснить больше, если это необходимо. Я люблю программирование, поэтому выкидывайте любые советы / проблемы, которые вы можете. Спасибо, что нашли время:)

Вот мой offers.php код:

<?php

require_once('startsession.php');
require_once('dbconnect.php');

if (!isset($_SESSION['user_id'])) {
    echo '<p class="login">Please <a href="login.php">log in</a> to access this page.</p>';
    exit();
}

require_once('navmenu.php');

$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);

if (isset($_GET['id']) && $_GET['action'] == 'confirm') {

    $adid = $_GET['id'];
    $userid = $_SESSION['user_id'];
    $cost = $_SESSION['cost'];
    $sellerid = $_SESSION['seller_id'];

    //Check if bid was already made
    $query = "SELECT * FROM transactions WHERE ad_id = '$adid' AND buyer_id = '$userid'";
    $data = mysqli_query($dbc, $query);
    $row = mysqli_num_rows($data);

    if ($row == 1) {
        echo '<p>Bid has been made</p>';
    } else {
        //If bid doesnt already exist insert bid
        $query = "INSERT INTO transactions (ad_id, buyer_id, seller_id, cost, status) VALUES ('$adid', '$userid', '$sellerid', '$cost', 'O')";
        $data = mysqli_query($dbc, $query);
    }
} else if (isset($_GET['id']) && $_GET['action'] == 'makeoffer') {

    $adid = $_GET['id'];
    $userid = $_SESSION['user_id'];

    //Check if bid was already made
    $query = "SELECT * FROM transactions WHERE ad_id = '$adid' AND buyer_id = '$userid'";
    $data = mysqli_query($dbc, $query);
    $row = mysqli_num_rows($data);

    if ($row == 1) {
        echo '<p>You have already made a bid on this..</p>';
    } else {
        echo '<form method="post" action="offers.php?id=' . $adid . '&action=confirm">';
        echo '<p>You are about to bid 5 Life Dollars.';
        echo '<input type="submit" value="Confirm" name="submit" /></p>';
        echo '</form>';
    }
} else if (isset($_GET['id'])) {

    $userid = $_SESSION['user_id'];

    //Get ad details
    $adid = $_GET['id'];

    $query = "SELECT * from ads WHERE id = '$adid'";
    $data = mysqli_query($dbc, $query);

    $row = mysqli_fetch_array($data);

    //echo ad details
    echo '<p>' . $row['ad_name'] . '<br>' . $row['ad_desc'] . '<br>' . 'Cost: ' . $row['timedollars']
    . ' Time Dollars . ' . '<br>';

    //Set session seller and cost
    $sellerid = $row['seller_id'];
    $_SESSION['seller_id'] = $sellerid;
    $_SESSION['cost'] = $row['timedollars'];

    //Check to see if a bid was already made
    $query = "SELECT * FROM transactions WHERE ad_id = '$adid' and buyer_id = '$userid'";
    $data = mysqli_query($dbc, $query);
    $row = mysqli_num_rows($data);

    if ($row == 0 && $userid != $sellerid) {
        echo '<a href="offers.php?id=' . $adid . '&action=makeoffer">Make Bid</a></p>';
    } else if ($row == 1) {
        echo 'Already bidded';
    }
} else {

    //Get all ads/offers
    $query = "SELECT * FROM ads WHERE ad_type = 'O'";
    $data = mysqli_query($dbc, $query);

    //echo all ads
    while ($row = mysqli_fetch_array($data)) {
        echo '<p>' . '<a href="offers.php?id=' . $row['id'] . '">' . $row['ad_name'] . '</a>' . '<br>' . $row['ad_desc'] . '</p>';
    }
}

mysqli_close($dbc);
?>

enter code here

Ответы [ 3 ]

2 голосов
/ 13 августа 2010

Это сложно, ха-ха.

Хорошо, поэтому одним из простых способов уменьшить возможность «взломать» ваш сайт было бы использование переменных «post» вместо «get». Таким образом, они не могут просто изменить адресную строку, они должны опубликовать свои переменные.

Я бы сделал это, чтобы сохранить «транзакцию» в базе данных. Таким образом, у вас будет таблица с session_id и action или чем-то похожим на столбцы. Затем, когда они загружают каждую «страницу» сценария, вместо того, чтобы получить то, где они находятся из строки запроса, вы запрашиваете у базы данных их session_id и получаете действие оттуда. Затем каждый раз, когда они выполняют действие, вы обновляете базу данных, чтобы сказать, в какой точке они находятся сейчас.

Еще один способ сделать это - поместить действие в переменную $ _SESSION и вызывать ее каждый раз.

1 голос
/ 13 августа 2010

Я быстро прочитал твой вопрос (ему нужно немного Major редактирование), и вещь, которая выскочила на меня, была ...

Я делаю все это на одномСтраница PHP под названием offer.php.Проще говоря, будет 4 страницы, сделанные из offer.php.Когда пользователь вначале просматривает раздел предложений (offer.php), он видит все предложения, затем он может щелкнуть предложение (offer.php? Id = X), а затем сделать ставку (offer.php? Id =).X & action = makebid), а затем подтвердите ставку (offer.php? Id = X & action = Подтвердить).

Я бы сказал, что такая большая функциональность в одном скрипте - это major запах кода.

Почему бы вместо этого не иметь 4 PHP-скрипта?

  • offers.php
  • an-offer.php
  • bid.php
  • confirm.php

Приложение

Как говорит @Thomas Clayton, вам нужно использовать несколько POST запросов здесь.Вы изменяете состояние сервера с помощью GET запросов, что является учебником BAD , поэтому мне хочется, чтобы вы анализировали HTML с помощью RegEx вместо .(что также было бы плохо)

Читайте в Википедии и на веб-сайте w3c о том, как GET является безопасным методом.

Читайте овеб-сайты, на которых возникла ошибка из-за изменения состояния при GET запросах:

0 голосов
/ 13 августа 2010

Я определенно согласен с использованием POST.что-то вроде:

<form method=POST action='offers.php'>
<input type=hidden name=id value=100>
<input type=hidden name=action value=confirm>

</form>

НО, имейте в виду, что на самом деле не мешает кому-то подделать представление.Это делает его гораздо менее удобным.

В конце я бы сказал, что если это действие может выполнить пользователь в любом случае, я бы не стал тратить много усилий на его предотвращение.То есть, если они могут зайти на сайт, найти идентификатор 200 и нажать «Подтвердить», то какая разница между этим и вводом вручную в адресную строку?Пока это влияет только на их учетную запись, это не является серьезной проблемой безопасности.

Как я уже сказал в одном из комментариев, ваша большая проблема - это инъекция sql, которую вы приглашаете, не экранируя идентификатор перед тем, как поместить их.в ваши sql запросы.Даже если вы делаете что-то вроде:

$id = $_GET['id'] + 0

Чтобы убедиться, что у вас есть номер, а не вредоносный текст.

Еще одна вещь, которую следует учитывать, - это использование оператора switch вместо if.Сделайте переключатель в зависимости от действия.Это будет гораздо более читабельным.

case ($action)
{
   'confirm':
      //do confirm stuff
      break;

   'makeoffer':
       // do offer stuff
       break;

   default:
      default stuff

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...