我正在创建一个简单的resister表单(resister.php
),一个登录表单(login.php
),并在php和checklogin.php
中检查经过身份验证的用户(MySQL
)。所有php文件都正常工作,checklogin.php
除外。每当我在login.php
文件中放入用户名和密码(存在于用户表中)时,它会显示警告消息(“密码不正确!”),而应将用户重定向到经过身份验证的主页(home.php
)。
resister.php
<!DOCTYPE html>
<html>
<head>
<title>My first PHP website</title>
</head>
<body>
<h2>Registration Page</h2>
<a href="index.php">Click here to go back</a><br/><br/>
<form action="register.php" method="post">
Enter Username: <input type="text" name="username" required="required" /><br/><br/>
Enter Password: <input type="password" name="password" required="required" /><br/><br/>
<input type="submit" value="Register" />
</form>
</body>
</html>
<?php
$con = mysqli_connect("localhost", "root","") or die(mysqli_error()); // Connect to server
mysqli_select_db($con,'first_db') or die("Cannot connect to database"); // Connect to database
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$username = mysqli_real_escape_string($con, $_POST['username']);
$password = mysqli_real_escape_string($con, $_POST['password']);
$bool = true;
$query = mysqli_query($con,"Select * from users"); //Query the users table
while ($row = mysqli_fetch_array($query)) { //display all rows from query
$table_users = $row['username']; // the first username row is passed on to $table_users, and so on until the query is finished
if ($username == $table_users) { // checks if there are any matching fields
$bool = false; // sets bool to false
print '<script>alert("Username already exist!");</script>'; // Prompts the user
print '<script>window.location.assign("register.php");</script>'; // redirects to register.php
}
}
if ($bool) { // checks if bool is true
mysqli_query($con, "INSERT INTO users (username, password) VALUES ('$username','$password')"); //Inserts the value to table users
print '<script>alert("Successfully Registered!");</script>'; // Prompts the user
print '<script>window.location.assign("register.php");</script>'; // redirects to register.php
}
}
?>
此代码工作正常。当我输入用户名和密码时,它存储在数据库(first_db)和表(用户)中。
现在让我们来看看login.php文件。此文件用于登录。
<!DOCTYPE html>
<html>
<head>
<title>My first PHP Website</title>
</head>
<body>
<h2>Login Page</h2>
<a href = "index.php">Click here to go back</a><br/><br/>
<form action="checklogin.php" method="POST">
Enter Username: <input type="text" name="username" required="required" /> <br/><br/>
Enter password: <input type="password" name="password" required="required" /> <br/><br/>
<input type="submit" value="Login"/>
</form>
</body>
</html>
Blow是用于身份验证的文件(checklogin.php
)。每当我输入用户名和密码(已重新注册并存储在数据库表中)时,它会提醒消息(“密码不正确!”)。
<?php
$con = mysqli_connect("localhost", "root","") or die(mysqli_error()); //Connect to server
mysqli_select_db($con,"first_db") or die("Cannot connect to database"); //Connect to database
session_start();
$username = mysqli_real_escape_string($con,$_POST['username']);
$password = mysqli_real_escape_string($con,$_POST['password']);
$query = mysqli_query($con,"SELECT * from users WHERE username='$username'"); //Query the users table if there are matching rows equal to $username
$exists = mysqli_num_rows($query); //Checks if username exists
$table_users = "";
$table_password = "";
if($exists > 0) //IF there are no returning rows or no existing username
{
while($row = mysqli_fetch_array($query)) //display all rows from query
{
$table_users = $row['username']; // the first username row is passed on to $table_users, and so on until the query is finished
$table_password = $row['password']; // the first password row is passed on to $table_users, and so on until the query is finished
}
if(($username == $table_users) && ($password == $table_password)) // checks if there are any matching fields
{
if($password == $table_password)
{
$_SESSION['users'] = $username; //set the username in a session. This serves as a global variable
header("location: home.php"); // redirects the user to the authenticated home page
}
}
else
{
Print '<script>alert("Incorrect Password!");</script>'; //Prompts the user
Print '<script>window.location.assign("login.php");</script>'; // redirects to login.php
}
}
else
{
Print '<script>alert("Incorrect Username!");</script>'; //Prompts the user
Print '<script>window.location.assign("login.php");</script>'; // redirects to login.php
}
?>
答案 0 :(得分:0)
我不知道这是否能解决您的问题,但我想指出您的代码存在的一些问题:
$query = mysqli_query($con,"Select * from users");
while ($row = mysqli_fetch_array($query)) {
$table_users = $row['username'];
if ($username == $table_users) {
$bool = false;
print '<script>alert("Username already exist!");</script>';
print '<script>window.location.assign("register.php");</script>';
}
}
if ($bool) {
mysqli_query($con, "INSERT INTO users (username, password) VALUES ('$username','$password')");
...
}
您使用一个查询在数据库中搜索重复的用户名,然后您发出第二个查询以插入新用户。这为两个用户同时注册相同的用户名留下了足够的空间。在繁忙的网站上,这不太可能发生。
解决此问题的规范方法是生成username
列UNIQUE
,并尝试插入新用户名。如果新用户名是重复的,则MySQL服务器将以error code 1062
回复。
$query = mysqli_query ($con, "INSERT INTO users (username, password) VALUES ('$username', '$password')");
if ($query) {
// Success
} else if (mysqli_errno ($con) === 1062) {
// Duplicate username
} else {
// Other database error
}
$username = mysqli_real_escape_string($con,$_POST['username']);
$password = mysqli_real_escape_string($con,$_POST['password']);
...
$table_users = $row['username'];
$table_password = $row['password'];
...
if(($username == $table_users) && ($password == $table_password))
{
if($password == $table_password)
请注意,您要将已转义的$username
和$password
与非转义的$tables_users
和$table_password
进行比较。如果您的用户名或密码中包含不常见的字符,则会导致检查失败。 (为什么要两次比较密码?)
resister.php
也有同样的错误。
$query = mysqli_query($con,"SELECT * from users WHERE username='$username'");
$exists = mysqli_num_rows($query);
...
if($exists > 0) {
while($row = mysqli_fetch_array($query)) {
$table_users = $row['username'];
$table_password = $row['password'];
}
if(($username == $table_users) && ($password == $table_password)) {
if($password == $table_password) {
$_SESSION['users'] = $username;
header("location: home.php");
}
...
首先,您要遍历数据库结果,直到找到最后一个。从逻辑上讲,应该只有一个匹配。如果是这样,您可以将while()
更改为if()
。
但是如果表中有重复的用户名,resister.php
可以使用,则只测试最后一个结果的密码。您可以通过将密码测试移到while()
循环中来解决此问题:
while($row = mysqli_fetch_array($query)) {
$table_users = $row['username'];
$table_password = $row['password'];
if(($username == $table_users) && ($password == $table_password)) {
if($password == $table_password) {
$_SESSION['users'] = $username;
header("location: home.php");
}
}
或者,更简单的是,将密码测试添加到查询本身:
$query = mysqli_query($con,"SELECT * from users WHERE username='$username'" AND password='$password');
if ($query) {
if (mysqli_num_rows ($query)) {
// Success
} else {
// Wrong username or password
}
} else {
// Database error
}
$username = mysqli_real_escape_string($con, $_POST['username']);
$password = mysqli_real_escape_string($con, $_POST['password']);
正确转出用户数据。这很好。但是,将明文密码存储在数据库中被认为是不好的做法。通常,您将计算密码的哈希值,并仅存储和比较哈希值。请参阅:PHP的Safe Password Hash FAQ。