通过GET更改DB的状态


Change the state of DB thru GET?

addCategory.php

<?php
$parentId = isset($_GET['parentId']) ? $_GET['parentId'] : 0;
$categoryName = $categoryDescription = "";
$fail = "";

if (isset($_POST['submit'])) {  
    if (isset($_POST['categoryName']))
        $categoryName = fix_string($_POST['categoryName']);
    if (isset($_POST['categoryDescription']))
        $categoryDescription = fix_string($_POST['categoryDescription']);
    $hidParentId = $_POST['hidParentId'];
}
$fail  = validate_category_name($categoryName);
$fail .= validate_category_description($categoryDescription);

echo "<html><head><title>An Example Form</title>";
if ($fail == "") {
  echo "success";
    header("Location: processCategory.php?action=add&categoryName=$categoryName&categoryDescription=$categoryDescription&hidparentId=$hidParentId");
    exit;
}
// Now output the HTML and JavaScript code
?>
<!-- The HTML section -->
<style>.signup { border: 1px solid #999999;
    font: normal 14px helvetica; color:#444444; }</style>
<script type="text/javascript">
function validate(form)
{
    fail  = validateCategoryName(form.categoryName.value)
    fail += validateCategoryDescription(form.categoryDescription.value)
    if (fail == "") return true
    else { alert(fail); return false }
}
</script></head><body>
<table class="signup" border="0" cellpadding="2"
    cellspacing="5" bgcolor="#eeeeee">
<th colspan="2" align="center">Add Category</th>
<?php
if (isset($_POST['submit'])) {
?>
<tr><td colspan="2">Sorry, the following errors were found<br />
in your form: <p><font color=red size=1><i><?php echo $fail ?></i></font></p>
</td></tr>
<?php 
}
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?parentId=<?php echo $parentId; ?>"
    onSubmit="return validate(this)">
     <tr><td>Category Name</td><td><input type="text" maxlength="32"
    name="categoryName" value="<?php echo $categoryName; ?>" /></td>
    </tr><tr><td>Category Description</td><td><input type="text" maxlength="32"
    name="categoryDescription" value="<?php echo $categoryDescription; ?>" /></td>
    <input type="hidden" name="hidparentId" value="<?php echo $parentId; ?>" />
</tr><tr><td colspan="2" align="center">
    <input type="submit" name="submit" value="ok" /></td>
</tr></form></table>
<!-- The JavaScript section -->
<script type="text/javascript">
function validateCategoryName(field) {
    if (field == "") return "No name entered.'n"
    return ""
}
function validateCategoryDescription(field) {
    if (field == "") return "No description entered.'n"
    return ""
}
</script></body></html>
<?php
// Finally, here are the PHP functions
function validate_category_name($field) {
    if ($field == "") return "No name entered<br />";
    return "";
}
function validate_category_description($field) {
    if ($field == "") return "No description entered<br />";
    return "";
}
function fix_string($string) {
    if (get_magic_quotes_gpc()) $string = stripslashes($string);
    return htmlentities ($string);
}
?>



processCategory.php

<?php
$action = isset($_GET['action']) ? $_GET['action'] : '';
switch ($action) {
    case 'add' :
        addCategory();
        break;
    case 'modify' :
        modifyCategory();
        break;
    case 'delete' :
        deleteCategory();
        break;
    default :
        // if action is not defined or unknown
        // move to main category page
        header('Location: index.php');
}

/*
    Add a category
*/
function addCategory() {

    $name        = $_GET['categoryName'];
    $description = $_GET['categoryDescription'];
    $parentId  = $_GET['hidparentId'];
    $sql   =  "INSERT INTO tbl_category (cat_parent_id, cat_name, cat_description) 
            VALUES ($parentId, '$name', '$description')";
    $result = dbQuery($sql) or die('Cannot add category' . mysql_error());
    header('Location: index.php?catId=' . $parentId);     
}
function modifyCategory() {
}
function deleteCategory() {
}
?>

请注意,我通过POST获得用户输入,然后将POST数据发送到相同的.php文件。。。。。。然后在验证后将这些数据发送到另一个.php文件THRU GET。。。。。将这些GET数据插入到DB中,然后在插入这些数据后,我们重定向到另一个页面。

我读到,如果您更改数据库的状态,则应该使用POST而不是GET。我认为这很糟糕,因为GET数据可以在URL中看到,这样用户就可以更改URL中数据库的状态,另一种情况是,当你点击刷新时,如果你使用POST,浏览器会警告你试图再次重复相同的方法,但如果你使用GET,浏览器不会警告你,所以最终会发布两次相同的数据。

在我的代码中,用户无法操作url来更改DB,因为一旦插入数据,我们就会重定向到不同的页面,而且刷新问题在这里也不是问题。

我想要一个分离的地方,在那里我处理我的输入,那就是processCategory.php.

我是个傻瓜,如果我做得对,请告诉我。

数据如何到达那里并不重要,它可以在途中进行修改。你可以把它放在GET或POST中,用户可以伪造它,提出自己的请求,或者中间的人可以修改它(除非你运行https(。

您的脚本容易受到addCategory函数中SQL注入的攻击。你应该修改它在最低限度,像这样:

function addCategory() {
    $name        = mysql_real_escape_string($_GET['categoryName']);
    $description = mysql_real_escape_string($_GET['categoryDescription']);
    $parentId  = mysql_real_escape_string($_GET['hidparentId']);
    $sql   =  "INSERT INTO tbl_category (cat_parent_id, cat_name, cat_description) 
            VALUES ($parentId, '$name', '$description')";
...

有人可以将SQL查询的一部分放入任何一个$_GET(或$_POST……不管是哪一个(中,并可能让它在您的服务器上执行。mysql_real_escape_string是为您提供的一个函数,用于确保恶意用户可能进入脚本的查询的任何部分都不会通过。图示如下:http://xkcd.com/327/

此外,您可能希望使用PDO和参数化查询进行查找,因为这些查询更安全。

至于用户修改内容并重新提交,您可以通过使用Nonces来防止这种情况。nonce是一种安全的东西,它是一个">n使用一次的数字"。一种非常简单的方法可以如下:当你向用户显示表单时,你应该在数据库中放入某种排序的数字,然后将该数字放入表单上的隐藏字段。当用户提交时,脚本会看到字段中的nonce,检查它是否在数据库中,然后将其删除。如果脚本找不到nonce,它知道它已经被使用了,所以它拒绝了用户的请求,因为该请求已经被处理了。为了进一步确保这一点,将用户的id与nonce一起放入数据库中(假设您有某种会话处理,可以为用户提供id(,这样用户就有了自己的nonce。更好的做法是给每个会话一个唯一的id,并将其与nonce一起使用。虽然这个系统并不完美,但它至少应该在用户意外刷新页面的情况下有所帮助。你可以把它想象成一个"请求id",一旦"请求id"被处理了,它就不能再被处理了。

同样,只要以某种方式验证数据,数据放在哪里并不重要。然而,一个限制是,一些浏览器(如IE的某些版本(倾向于不允许长度超过2048个字符左右的URL。POST数据通常没有那么有限(除了PHP本身(,因此如果你计划发送大量数据(如论坛上的帖子(,你可能会想使用POST。如果你发送的数据很少(比如推特(,你可以使用GET。此外,密码不应该通过GET发送,因为用户的浏览器可能会将其保存在历史记录中,并且您不希望密码在历史记录的任何地方浮动。。。

编辑:顺便说一句,你不一定要有两个单独的URL来处理你的数据。您只需从processCategory.php中删除任何HTML部分,在addCategory.php的顶部使用require processCategory.php,并将其替换为以下内容:

addCategory();
header("Location: someSuccessPage.php");

这没什么大不了的,但使用过多的重定向和请求会让你的网站速度慢一点,还会导致你的服务器接收到比它需要的更多的请求。每次你更改位置标头时,它都会发送一个302,让用户的浏览器从服务器请求另一个URL。