好吧,我正在构建一个新的应用程序,并决定使用PDO进行数据库访问。(我对PDO完全陌生,但我觉得这是访问数据库的最佳方式)。
现在,我的登录脚本非常简单。它检查数据库中是否有具有给定用户名的用户(从登录表单中),尝试将给定密码与明文存储的密码匹配(还没有加密/解密),并根据需要重定向用户。下面是一个简单的序列图:
Login Screen ---(user enters credentials)--->Login Handler---(gets user details and compares pw)-->if (pw == stored pw)--->dashboard / else --->login w/ error msg
很抱歉,如果这很难阅读,我不确定代表流量的最佳方式。。。不管怎样。。。
这是我的问题:我输入了正确的用户名和密码(甚至区分大小写!),并且总是被重定向回登录屏幕并显示错误消息。但是,如果我只是通过url栏转到仪表板,我就不会被重定向回登录屏幕(如果没有设置会话,我应该是这样),并且我的用户名会显示在导航栏中(就像我正确登录一样)。
再次,如果这很难理解,我很抱歉。这有点难以简单解释。如果这是一个问题,我也许可以做一些电影放映来更好地解释。不管怎样,这是我的代码:
loginHandler.php
if(!isset($_POST['username']) || !isset($_POST['password'])){
header('Location: login.php?error=pass');
}
$username = $_POST['username'];
$pass = $_POST['password'];
//TODO: crypt password
try{
$DB = new PDO("mysql:host=127.0.0.1;port=8889;dbname=cTix", 'root', 'root'); //TODO: change this when uploading to webserver
$STH = $DB->prepare("SELECT * FROM users WHERE username = $username LIMIT 0, 1");
$STH->setFetchMode(PDO::FETCH_OBJ);
$STH->execute();
$u = $STH->fetch();
if($pass == $u->password){
session_start();
$_SESSION['uid'] = $u->id; //TODO: securely store uid
header('Location: index.php');
} else {
//echo 'Your Password: ' . $pass . ' - Correct Password: ' . $u->password;
header('Location: login.php?error=pass');
}
} catch(PDOException $e){
//echo $e->getMessage();
header('Location: login.php?error=true');
exit;
}
以下是检索dashboard.php用户名的代码:
function connection(){
$host = 'localhost';
$dbname = 'cTix';
$user = 'root';
$pass = 'root';
try {
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
return $DBH;
} catch(PDOException $e){
echo $e->getMessage();
return null;
}
}
function getUserById($id){
$DB = connection();
$STH = $DB->query("SELECT * FROM users WHERE id = $id");
$STH->setFetchMode(PDO::FETCH_OBJ);
$u = $STH->fetch();
$DB = null;
return $u;
}
function getUserName(){
echo getUserById(getCurrentUserId())->name;
}
如果我能提供任何其他信息,或者我能提供的任何更有帮助的信息,请告诉我!
不幸的是,如果没有解决这个愚蠢的登录问题,我就无法在这个应用程序上取得任何进展,所以任何帮助都将不胜感激!非常感谢!
以下是您的问题所在:
$STH = $DB->prepare("SELECT * FROM users WHERE username = $username LIMIT 0, 1");
您将用户名连接到SQL字符串中,但不引用它。我怀疑这将解决问题:
$STH = $DB->prepare("SELECT * FROM users WHERE username = '$username' LIMIT 0, 1");
无论如何
您应该研究如何使用绑定参数。您已经在使用PDO,但仍在SQL中编写用户输入的代码,绑定参数可以避免这种情况——它也可以避免这个问题。
这应该有效,但我还没有测试过:
$STH = $DB->prepare('SELECT * FROM users WHERE username = ? LIMIT 0, 1');
$STH->bindParam(1, $username);
$STH->setFetchMode(PDO::FETCH_OBJ);
$STH->execute();