为了避免 SQL 注入,我尝试使用准备好的语句制作 PHP 脚本。我还创建了 3 个 php 文件。
db_connect.php
(这里存储了连接数据库的所有信息)functions.php
(创建会话,检查登录尝试和功能login
- 我可能犯了一个错误但找不到它)process_login.php
(上面两个文件的集合。如果没有 POST 变量发送到此页面,它还会重定向到login_success
错误页面或打印Invalid request )。
另外可能是错误所在,因为每次尝试插入一些值时我都会functions.php
收到无效请求。无论字段是空的还是它们包含来自数据库用户的值。
<?php
function sec_session_start() {
$session_name = 'sec_session_id'; // Set a custom session name
$secure = false; // Set to true if using https.
$httponly = true; // This stops javascript being able to access the session id.
ini_set('session.use_only_cookies', 1); // Forces sessions to only use cookies.
$cookieParams = session_get_cookie_params(); // Gets current cookies params.
session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly);
session_name($session_name); // Sets the session name to the one set above.
session_start(); // Start the php session
session_regenerate_id(true); // regenerated the session, delete the old one.
}
function login($postcode, $ref, $mysqli) {
// Using prepared Statements means that SQL injection is not possible.
if ($stmt = $mysqli->prepare("SELECT ref_no, postcode FROM customers WHERE ref_no = ? LIMIT 1")) {
$stmt->bind_param('ss', $postcode,$ref); // Bind "$email" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->bind_result($dbref,$dbpostcode); // get variables from result.
// $stmt->fetch();
$a = array();
while ($stmt->fetch()) {
$a = array('ref' => $dbref , 'postcode' => $dbpostcode);
}
if ($_POST['ref']==$dbref && $_POST['postcode']==$dbpostcode){ // If the user exists
// We check if the account is locked from too many login attempts
if(checkbrute($ref, $mysqli) == true) {
// Account is locked
return false;
} else {
if($dbref == $ref) { // Check if the password in the database matches the password the user submitted.
// Password is correct!
$ip_address = $_SERVER['REMOTE_ADDR']; // Get the IP address of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT']; // Get the user-agent string of the user.
if(preg_match("/^[0-9a-zA-Z]{5,7}$/", $_POST["postcode"]) === 0)
'<p class="errText">Please enter valid postcode!</p>';
else{ $_SESSION['postcode'] = $postcode;}
if(preg_match("/^[0-9]{4,6}$/", $_POST["ref"]) === 0) '<p class="errText">Please enter valid reference number ! </p>';
else{
$_SESSION['ref'] = $ref;}
// Login successful.
return true;
} else {
// Password is not correct
// We record this attempt in the database
$now = time();
$mysqli->query("INSERT INTO login_attempts (ref_no, time) VALUES ('$ref', '$now')");
return false;
}
}
} else {
// No user exists.
return false;
}
}
}
function checkbrute($ref, $mysqli) {
// Get timestamp of current time
$now = time();
// All login attempts are counted from the past 2 hours.
$valid_attempts = $now - (2 * 60 * 60);
if ($stmt = $mysqli->prepare("SELECT time FROM login_attempts WHERE ref_no = ? AND time > '$valid_attempts'")) {
$stmt->bind_param('i', $ref);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
// If there has been more than 3 failed logins
if($stmt->num_rows > 3) {
return true;
} else {
return false;
}
}
}
?>
这就是process_login.php
用户验证失败的地方。
<?php
include 'db_connect.php';
include 'functions.php';
sec_session_start(); //
if(isset($_POST['postcode'], $_POST['ref'])) {
if(login($postcode, $ref, $mysqli) == true) {
// Login success
echo 'Success: You have been logged in!';
} else {
// Login failed
header('Location: ./login.php?error=1');
}
} else {
// The correct POST variables were not sent to this page.
echo 'Invalid Request';
}
?>
任何帮助都将受到欢迎。谢谢。