簡體   English   中英

如何使用php在注冊期間檢查用戶可用性?

[英]How to check user availability during registration using php?

我想讓我的注冊過程更加安全,系統將只接受新用戶名。 下面顯示了我用於 signup.php 的代碼。 請幫我。

你認為這段代碼對於 SQL 注入是否足夠安全? 如果不是,哪些代碼可以是安全的,以及如何安全?

<?php       
include"connection.php";          

    if (!isset($_POST['submit'])) //if the user clicks the submit button then the PHP code POST the details 
{
    $user_name = $_POST['username']; 
    $user_password = $_POST['password']; 
    $user_email = $_POST['email']; 

    if($user_name && $user_password && $user_email)
        {
            $query = mysql_query("INSERT INTO users (username, password, email, type) 
            VALUES ('$user_name', '$user_password', '$user_email', '0')");
            mysql_query($query); 
 echo '<script type="text/javascript">alert("You have been registered");</script>';
    }
    else {
        echo '<script type="text/javascript">alert("All fields required");</script>'; 
       header("location:user_create.html");
    }
}

?>

首先,您應該更改以下內容:

if (!isset($_POST['submit'])) //if the user clicks the submit button then the PHP code POST the details 
{
    $user_name = $_POST['username']; 
    $user_password = $_POST['password']; 
    $user_email = $_POST['email'];
    // ...
}

對此:

if (isset($_POST['submit'])) //if the user clicks the submit button then the PHP code POST the details 
{
    $user_name = mysql_real_escape_string($_POST['username']); 
    $user_password = mysql_real_escape_string($_POST['password']); 
    $user_email = mysql_real_escape_string(($_POST['email']);
    // ...
}

然后在運行mysql_query($query); 您應該通過使用select語句在數據庫中查詢來檢查用戶是否存在,例如:

$query = sprintf("SELECT * FROM users WHERE email='%s' OR username='%s'", $user_email, $user_name);
$result = mysql_query($query);
if(!$result) {
    $query = sprintf("INSERT INTO users (username, password, email, type) VALUES ('%s','%s','%s','%d')", $user_name, $user_password, $user_email, 0));
    mysql_query($query);
    if(mysql_affected_rows() > 0)
    {
        // inserted
    }
    else {
        // not inserted
    }
}

MySQL 擴展自 PHP 5.5.0 起已棄用,將來會被刪除。 相反,應使用MySQLiPDO_MySQL擴展。

為了防止 SQL 注入,您必須預處理所有變量(SESSION、COOKIE、GET、POST 和地址欄(又名 $_SERVER['REQUEST_URI'])。

對於這種方法,PHP 有一個名為 filter_vars 和 filter_var 的命令。

大多數人會使用 strip_slashes 或 mysql_escape_string 或 mysql_real_escape_string 。 雖然這些確實達到了它們的目的,但我建議在 filter_vars 之后運行那些,並且為了更加安全,如果您知道數據類型,請檢查它。

不要使用 preg_match() 因為它可以執行 $haystack 參數中的代碼。

$filterd = filter_var($_POST['username'], FILTER_SANITIZE_STRIPPED);
if($filtered) {
    $filtered = sprintf("%s", mysql_real_escape_string($filtered));
    // Now it should be safe to use preg_replace()

} else {
    echo 'Username is invalid';
    exit(0);
}

// Your database code here

如果您知道要傳遞的數據的類型以跟進檢查,這也是一種很好的做法,例如

is_int($filtered);

甚至通過限制輸入來進一步驗證,例如,如果您正在尋找一個范圍內的數字,您將執行以下操作:

$filterd = filter_var($_POST['fieldnumber'], FILTER_SANITIZE_STRIPPED);
if($filtered && is_numeric($filtered)) {
    $filtered = sprintf("%d", mysql_real_escape_string($filtered));

    $filtered = intval($filtered);

    // Constrain the integer value to a number between 0 and 255
    $filtered = max(255, min(0, $adjust));

    // Now it should be safe to use preg_replace()



} else {
    echo 'Username is invalid';
    exit(0);
}

// Your database code here

PHP 是一種了不起的語言,因為它允許您用不同的方法做很多事情。 因此,還有另一種方法是 filter_var 包裝器,稱為 filter_input 。

在 php.net 的官方網站上有很多文檔和使用示例,這個鏈接
http://ca3.php.net/manual/en/function.filter-input.php

簡而言之,它允許您傳遞另一個參數來指定您希望過濾的輸入類型(SESSION、COOKIE、GET、POST 等),並且可以說比僅使用filter_var更安全

這是我提出的完整解決方案,它包含過濾器和使用 mysqli 連接的准備好的語句。 准備好的語句消除了對數據進行任何轉義的需要,因為這是自動處理的。 還進行了其他檢查,以幫助保護您免受 SQL 注入。

// Define database connection details
define('MYSQL_SERVER',      'localhost');
define('MYSQL_USER',        'root');
define('MYSQL_PASSWORD',    '');
define('MYSQL_DATABASE',    'test');

// Define SQL query strings
define('SQL_USERCHECK',     "SELECT email,username FROM users WHERE email=? OR username=?");
define('SQL_USERINSERT',    "INSERT INTO users (username, password, email, type) VALUES (?, ?, ?, ?)";

if(isset($_POST['submit'])) {
    // Sanitize Variables from POST
    $username   = filter_input(INPUT_POST,  'username', FILTER_SANITIZE_STRIPPED);
    $password   = filter_input(INPUT_POST,  'password', FILTER_SANITIZE_STRIPPED);
    $email      = filter_input(INPUT_POST,  'email',    FILTER_SANITIZE_EMAIL);

    $user_added = false;

    // Check if username, password, and email exist after sanitization.
    if($username && $password && $email) {

        // Call custom function below for inserting
        if(insert_user($username, $password, $email)) {
            $user_added = true;
            echo '<script type="text/javascript">alert("You have been registered");</script>';
        }

    }

    // If user was not added it means that the user exists,
    // or the values for username,password,email were not valid
    // after filtering.
    if(!$user_added) {
        // Added the redirect to Javascript for you.
        echo '<script type="text/javascript">alert("All fields are required"); window.location.replace(\'user_create.html\')</script>';     
    }
}

function insert_user($username, $password, $email) {
    $user_found = false;
    $user_inserted = false;

    $errors = 0;

    $cn = new mysqli(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE);

    if (mysqli_connect_errno()) {
        printf("Connection failed: %s\n", mysqli_connect_error());
        exit(0);
    }

    // Prepare the Username || Email check
    if ($s = $mysqli->prepare(SQL_USERCHECK)) {

        if(
            // Bind paramaters
            $s->bind_param("s", $username) &&
            $s->bind_param("s", $email)
        ) {
            $s->execute();
            if($row = $stmt->fetch_row()) {
                    // User exists;
                    $user_found = true;
            }
        } else {
            // One of the params did not bind
            $errors++;
        }
        $s->close();
    }

    // If user not found, Insert record
    if(!$user_found && $errors == 0) {
        $type = 0; // You have  "type='0'"  in your SQL insert statement
        if ($s = $mysqli->prepare(SQL_USERINSERT)) {

            if(
                // Bind paramaters
                $s->bind_param("s", $username) &&
                $s->bind_param("s", $password) &&
                $s->bind_param("s", $email) &&
                $s->bind_param("i", $type)
            ) {
                $s->execute();
                if($stmt->affected_rows > 0) {
                    // User was added to the database
                    $user_inserted = true;
                }
            } else {
                // One of the params did not bind
                $errors++;
            }
            $s->close();
        }
    }

    $cn->close();
    return $user_inserted;

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM