![](/img/trans.png)
[英]How to build restriction on user availability during registration using 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
}
}
為了防止 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.