使用php MySQL和HTML进行登录检查
我正在为一项作业建立一个网站的登录页面。当我在检查用户详细信息的文件中散列密码时,它与数据库中存储的散列密码不匹配。代码总是转到最后一个else语句,并使用错误的密码sv等于1将我重新链接到登录页面。如果我没有对密码进行散列,那么将散列后的密码从数据库复制并粘贴到登录表单中。如果有人能帮忙,我们将不胜感激使用php MySQL和HTML进行登录检查,php,html,mysql,authentication,hash,Php,Html,Mysql,Authentication,Hash,我正在为一项作业建立一个网站的登录页面。当我在检查用户详细信息的文件中散列密码时,它与数据库中存储的散列密码不匹配。代码总是转到最后一个else语句,并使用错误的密码sv等于1将我重新链接到登录页面。如果我没有对密码进行散列,那么将散列后的密码从数据库复制并粘贴到登录表单中。如果有人能帮忙,我们将不胜感激 ini_set('display_errors', 1); ini_set('log_errors',1); error_reporting(E
ini_set('display_errors', 1);
ini_set('log_errors',1);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
session_start();
$email = $_POST["email"];
$pass1 = $_POST["pass"];
$pass = hash('sha256', $pass1);
if(isset($_SESSION['user_type']))
{
unset($_SESSION['user_type']);
}
include("group_detail.php");
$query = "SELECT * from employee WHERE email = '$email' AND password = '$pass'";
$result_employee = $db->query($query);
$employee_row = mysqli_fetch_assoc($result_employee);
if(!empty($employee_row)){
$_SESSION['id'] = $employee_row['employee_ID'];
$_SESSION['name'] = $employee_row['name'];
$_SESSION['user_type'] = $employee_row['title'];
header('Location: homepage.html');
}else{
$query = "SELECT * from customer WHERE email = '$email' AND password = '$pass'";
$result_customer = $db->query($query);
$customer_row = mysqli_fetch_assoc($result_customer);
if(!empty($customer_row)){
$_SESSION['id'] = $customer_row['customer_ID'];
$_SESSION['name'] = $customer_row['name'];
$_SESSION['user_type'] = 'Customer';
$_SESSION['email'] = $customer_row['email'];
header('Location: homepage.html');
}
else{
$_SESSION['wrong_password'] = 1;
header('Location: login.php');
}
}
注册码
<<?php
// this code checks all reuired fields are filled in appropriately
ini_set('display_errors', 1);
ini_set('log_errors',1);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
session_start();
$nameErr = $phoneErr = $emailErr = $passwordErr = "";
$name = $address = $eircode = $email = $password = $phone = "";
$employee_ID = 0;
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
echo $nameErr;
if (empty($_POST["name"])) {
$nameErr = "Your name is required for registration";
} else {
$name = test_input($_POST["name"]);
if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
$nameErr = "Only letters and a space allowed";
}
}
if (empty($_POST["phone"])) {
$phoneErr = "Your phone number is required for registration";
} else {
$phone = test_input($_POST["phone"]);
}
if(empty($_POST['email']))
{
$emailErr = "Your Email is required for registration";
} else {
include ("group_detail.php");
$email_test = test_input($_POST["email"]);
$sql = "SELECT * from customer WHERE email = '$email_test'";
// Checks if another account uses this email
$result = $db->query($sql); // runs the query
$num_rows_3= mysqli_num_rows($result); // counts how many rows the query applies to
if($num_rows_3 == 0){
// Sets email value if no one else has used this email to sign up before
$email = test_input($_POST["email"]);
}
else{
// Lets the customer know this email is already in use
$emailErr = "Another account has previously been registered with this email. If this is you, you can login ";
}
}
if(empty($_POST['pass1']))
{
$passwordErr = "Password required";
} else {
$pass1 = $_POST['pass1'];
$pass2 = $_POST['pass2'];
if($pass1 == $pass2){
$pass = hash('sha256',$pass1);
// $pass = $pass1;
} else{
$passwordErr = "The passwords you enter must match";
}
}
if(empty($_POST['address']))
{
$address = "";
}else{
$address = test_input($_POST['address']);
}
if(empty($_POST['eircode']))
{
$eircode = "";
}else{
$eircode = test_input($_POST['eircode']);
}
if ($phoneErr == "" && $nameErr == "" && $passwordErr == "" && $emailErr == "")
{
// This code enters the data from the form into the customer table
include ("group_detail.php");
$q = "INSERT INTO customer(";
$q .= "name, phone, password, email, address, eircode";
$q .= ") VALUES (";
$q .= "'$name', '$phone', '$pass', '$email', '$address', '$eircode')";
$result = $db->query($q);
$sql = "SELECT customer_ID FROM customer ORDER BY customer_ID DESC LIMIT 1";
$result1 = $db->query($sql);
$row = mysqli_fetch_assoc($result1);
$_SESSION['customer'] = $row['customer_ID'];
header('Location: homepage.html');
}
}
?>
解决方案
您的字段长度不正确。当您使用SHA256
哈希函数时,您会得到如下输出:
ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f // password123
如果密码字段仅为15个字符
,则保存的值将被截断:
ef92b778bafe771
但是,在比较过程中,登录脚本中的完整值用于数据库中存储的截断版本,因此不存在匹配项。因为,正如你在上面看到的,它们是不同的
要修复此问题,您需要更改表,使字段至少为varchar(64)
。然后,新帐户将按预期工作(注意:旧哈希仍然无法工作-它们需要重做!)
补充资料
您的代码还有一些其他问题
您不应该将变量直接放入代码中。相反,在以后绑定变量时,最好使用带有参数化查询的准备语句。
- 这基本上意味着在查询中,我们使用一个占位符
?
,其中我们需要一个变量,然后将
变量绑定到占位符
- 这主要是为了防止SQL注入和防止错误输入
最好使用PHP内置函数password.*
来hash
和验证密码。
- 它比简单地使用
hash
盐
是自动生成的,可以保护您免受彩虹表之类的影响
password\u hash
的默认算法要求字段长度为60+
个字符
不需要在会话中存储多余的数据
- 数据已经存储在数据库中,因此只需在需要时获取它即可
似乎您有一个表用于客户
,另一个表用于员工
- 这不是一个好的设计,应该为
用户
设置一个表,然后您可以为员工
、客户
、供应商
等设置标志
test\u输入
函数执行通常在显示而不是保存时执行的功能
下面是解决上述部分问题的快速重写(注意:下面的代码不完整,例如,它不会执行所有相同的验证-例如,检查非法字符-仅用于说明目的)
注册
<?php
ini_set('display_errors', true);
ini_set('log_errors', true);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
session_start();
$errors = [];
$name = $_POST["name"] ?? null;
$phone = $_POST["phone"] ?? null;
$email = $_POST['email'] ?? null;
$address = $_POST['address'] ?? null;
$eircode = $_POST['eircode'] ?? null;
$pass1 = $_POST['pass1'] ?? null;
$pass2 = $_POST['pass2'] ?? null;
// Check passwords are the same and assign hash to $pass
$pass = $pass1 === $pass2 ? password_hash($pass1, PASSWORD_DEFAULT) : null;
// Check the required fields are present and not empty
if (!$name || !$phone || !$email || !$pass) {
$errors[] = "Required fields are missing.";
}
// Check if the email address already exists in the DB
$checkEmailExistsSQL = "SELECT COUNT(*) as countEmails FROM user WHERE email = ?";
$checkEmailExistsQuery = $mysqli->prepare($checkEmailExistsSQL);
$checkEmailExistsQuery->bind_param("s", $email);
$checkEmailExistsQuery->execute();
$emailExists = $checkEmailExistsQuery->get_result()->fetch_assoc()["countEmails"];
if ($emailExists !== 0) {
$errors[] = "The email address already exists in the DB";
}
// Check if there were errors and output them; then exit the script
if (count($errors)) {
foreach($errors as $error) {
echo $error, PHP_EOL;
}
exit;
}
include("group_detail.php");
$insertSQL = "
INSERT INTO user
(name, phone, password, email, address, eircode)
VALUES
(?, ?, ?, ?, ?, ?)
";
$insertQuery = $mysqli->prepare($insertSQL);
$insertQuery->bind_param("ssssss", $name, $phone, $pass, $email, $address, $eircode);
$insertQuery->execute();
// Success the user is registered
(可能)旁注:不要使用字符串插值或串联将值获取到SQL查询中。这很容易出错,并且可能使您的程序容易受到SQL注入攻击。使用参数化查询。请参阅和。我们还需要查看注册代码我们需要注册后端代码,不是前端code@SamRaskul鼓励使用预先准备好的语句可能比使用mysqli
函数来转义字符串要好?@SamRaskul就像你说的那样,password\u hash
在PHP中优先用于哈希密码。。。准备好的语句是防止SQL注入的标准;使用mysqli | PDO
。
<?php
ini_set('display_errors', true);
ini_set('log_errors', true);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
session_start();
$email = $_POST["email"] ?? null;
$pass = $_POST["pass"] ?? null;
// You can remove the old user id. But you don't need to
//
// There's no need to store excess data on the user in
// the SESSION super global; any data that you need
// access to can be retrieved from the DB at will.
// Copying data into SESSION only eats into memory.
unset($_SESSION["id"]);
// Check that something was submitted for email and password
if (!$email || !$pass) {
echo "Error: all fields need to be completed";
exit;
}
include("group_detail.php");
$sql = "SELECT id, password FROM user WHERE email = ?";
$query = $mysqli->prepare($sql);
$query->bind_param("s", $email);
$query->execute();
// Check to see if the email address is registered.
// Then check to see if the password is a match.
if (
!($user = $query->get_result()->fetch_assoc())
|| !password_verify($pass, $user["password"])
) {
echo "Error: the email address or password isn't correct";
exit;
}
// Success the user is logged on
//
$_SESSION["id"] = $user["id"];