我已经在这里多次建议开始将我的代码更改为PDO,并且我终于完成了这项工作。我的问题是我在转换现有的登录脚本时遇到了难以置信的困难。对于下面代码的最后几行(在$result = $query->fetchAll();
行之后),我无法在线找到任何可以帮助我重新编写代码的资源:
$username = $_POST['username'];
$password = $_POST['password'];
$db=getConnection();
$username = mysql_real_escape_string($username);
$query = $db->prepare( "SELECT password, salt, 'employer' as user_type
FROM JB_Employer
WHERE Username = '$username'
UNION
SELECT password, salt, 'jobseeker' as user_type
FROM JB_Jobseeker
WHERE User_Name = '$username'");
$result = $query->fetchAll();
$qData = mysql_fetch_array($result, MYSQL_ASSOC);
$hash = hash('sha256', $qData['salt'] . hash('sha256', $password) );
if ($result -> rowcount() <1 ;) { print “Fail, No such user”;}
if ($hash != $qData['password']) { header('Location: register.php?loginStatus=fail'); exit;}
else {$_SESSION['user'] = $username;
$_SESSION['permission'] = $qData['user_type'];}
任何人都可以建议我如何实现这个目标吗?
答案 0 :(得分:2)
看看这个,请重新调整您的代码,特别是关于XSS漏洞!此外,为了一个好的开发人员的缘故,重构/重写您的数据库。这是最好的,但是要走的路。
此外,代码未经测试。
<?php
$db = getConnection(); //assuming you are returning a PDO object here!
$username = getUsername(); //assuming you are NOT escaping the username!
$password = getPassword(); //assuming your hashed password here!
$query = "SELECT password, salt, 'emplyer' as user_type
FROM JB_Employer
WHERE Username = :username
UNION
SELECT password, salt, 'jobseeker' as user_type
FROM JB_Jobseeker
WHERE User_Name = :username";
//$statement == PDOStatement
$statement = $db->prepare($query);
//bind the $username param to :username, this is the real power of PDO,
//no more SQL Injections. Don't use mysql_real_escape-esque things!
//they are not nececary with PDO
$statement->bindParam(":username", $username);
//execute the statement
if($statement->execute()){
$result = $statement->fetchAll();
$rowCount = count($result);
if($rowCount < 1){
// redirect?
die("No Such user");
}else{
// more than one user can be possible, this is not the correct way, but it appears to be your way so let's continue
$firstRow = $result[0];
if( isPasswordEqual($firstRow['salt'], $password) ){
$_SESSION['user'] = $username; //security risk here. Vulnerable for XXS
$_SESSION['permission'] = $firstRow['user_type'];
}else{
//Don't tell them this! It will give them knowledge of which accounts do exist.
//Just say some general message like "login failed"
die("wrong information");
}
}
}
答案 1 :(得分:0)
您应该考虑重命名变量以使其更有意义。特别是,$db->prepare()
会返回语句,而不是查询。您传递一个查询,它准备该查询并返回一个语句。如果你遵循这个命名惯例,它将为你节省麻烦。
那就是说,你应该改变这段代码:
$result = $query->fetchAll();
$qData = mysql_fetch_array($result, MYSQL_ASSOC);
进入这个:
$qData = $query->fetch(\PDO::FETCH_ASSOC);
其余的应该排成一行。 PDOStatement::fetch(\PDO::FETCH_ASSOC)
会返回一个关联数组,就像mysql_fetch_array(..., MYSQL_ASSOC)
或mysql_fetch_assoc()
一样。
修改:此外,您需要将$result->rowCount()
更改为$query->rowCount()
。