PHP 准备语句登录
PHP Prepared statement login
我正在为我的登录系统添加密码散列和 SQL 注入防御。目前,我 运行 出错了。
<?php
session_start(); //start the session for user profile page
define('DB_HOST','localhost');
define('DB_NAME','test'); //name of database
define('DB_USER','root'); //mysql user
define('DB_PASSWORD',''); //mysql password
$con = new PDO('mysql:host=localhost;dbname=test','root','');
function SignIn($con){
$user = $_POST['user']; //user input field from html
$pass = $_POST['pass']; //pass input field from html
if(isset($_POST['user'])){ //checking the 'user' name which is from Sign-in.html, is it empty or have some text
$query = $con->prepare("SELECT * FROM UserName where userName = :user") or die(mysqli_connect_error());
$query->bindParam(':user',$user);
$query->execute();
$username = $query->fetchColumn(1);
$pw = $query->fetchColumn(2);//hashed password in database
//check username and password
if($user==$username && password_verify($pass, $pw)) {
// $user and $pass are from POST
// $username and $pw are from the rows
//$_SESSION['userName'] = $row['pass'];
echo "Successfully logged in.";
}
else {
echo "Invalid.";
}
}
else{
echo "INVALID LOGIN";
}
}
if(isset($_POST['submit'])){
SignIn($con);
}
?>
在上面的代码中,当我输入有效的用户名和密码时,系统打印出"Invalid"。这可能是 if 语句中 password_verify() 的错误(因为如果我删除它,我就成功登录了)。我很确定我已经正确地完成了查询的准备、绑定和执行?有谁知道它为什么这样做?
谢谢!
使用
// it will be an array('name' => 'John', 'password_hash' => 'abcd')
// or FALSE if user not found
$storedUser = $query->fetch(PDO::FETCH_ASSOC);
而不是
$username = $query->fetchColumn(1);
$pw = $query->fetchColumn(2);
因为 fetchColumn 移动结果的游标。所以第一次调用提取第一行的 1 列,第二次调用将从第二行提取数据!
您正在执行 SELECT *,并使用 fetchColumn,因此结果取决于返回的列顺序。您应该 select 您需要的特定列,或者将整行作为关联数组获取,然后按列名访问它。
还有其他两个问题需要解决:
- 您不应该像使用 PDO 那样使用 mysqli_connect_error()。正确的函数是 $con->errorInfo().
- 您正在使用连接设置定义一些常量,但您没有在 PDO() 调用中使用它们,而是重复这些值。
我正在为我的登录系统添加密码散列和 SQL 注入防御。目前,我 运行 出错了。
<?php
session_start(); //start the session for user profile page
define('DB_HOST','localhost');
define('DB_NAME','test'); //name of database
define('DB_USER','root'); //mysql user
define('DB_PASSWORD',''); //mysql password
$con = new PDO('mysql:host=localhost;dbname=test','root','');
function SignIn($con){
$user = $_POST['user']; //user input field from html
$pass = $_POST['pass']; //pass input field from html
if(isset($_POST['user'])){ //checking the 'user' name which is from Sign-in.html, is it empty or have some text
$query = $con->prepare("SELECT * FROM UserName where userName = :user") or die(mysqli_connect_error());
$query->bindParam(':user',$user);
$query->execute();
$username = $query->fetchColumn(1);
$pw = $query->fetchColumn(2);//hashed password in database
//check username and password
if($user==$username && password_verify($pass, $pw)) {
// $user and $pass are from POST
// $username and $pw are from the rows
//$_SESSION['userName'] = $row['pass'];
echo "Successfully logged in.";
}
else {
echo "Invalid.";
}
}
else{
echo "INVALID LOGIN";
}
}
if(isset($_POST['submit'])){
SignIn($con);
}
?>
在上面的代码中,当我输入有效的用户名和密码时,系统打印出"Invalid"。这可能是 if 语句中 password_verify() 的错误(因为如果我删除它,我就成功登录了)。我很确定我已经正确地完成了查询的准备、绑定和执行?有谁知道它为什么这样做?
谢谢!
使用
// it will be an array('name' => 'John', 'password_hash' => 'abcd')
// or FALSE if user not found
$storedUser = $query->fetch(PDO::FETCH_ASSOC);
而不是
$username = $query->fetchColumn(1);
$pw = $query->fetchColumn(2);
因为 fetchColumn 移动结果的游标。所以第一次调用提取第一行的 1 列,第二次调用将从第二行提取数据!
您正在执行 SELECT *,并使用 fetchColumn,因此结果取决于返回的列顺序。您应该 select 您需要的特定列,或者将整行作为关联数组获取,然后按列名访问它。
还有其他两个问题需要解决:
- 您不应该像使用 PDO 那样使用 mysqli_connect_error()。正确的函数是 $con->errorInfo().
- 您正在使用连接设置定义一些常量,但您没有在 PDO() 调用中使用它们,而是重复这些值。