我正在尝试创建一个登录系统,用于检查用户角色并重定向到相应的仪表板,同时禁止用户手动输入他人的仪表板URL。
登录操作很好,但对用户角色的检查就不那么好了。
该网站为每个角色都有一个面板,每个面板的顶部是:
session_start();
if(!$_SESSION['sess_role'] == 'role1') {
header('location:../../index.php');
}
当你还没有登录时,它似乎可以正常工作,因为"sess_role"属性不匹配,所以会正确地将你送回索引页面,但一旦我与任何用户登录,我就可以通过手动输入URL来进入每个仪表板,尽管没有正确的"角色"。
这是登录代码:
$msg = "";
if(isset($_POST['submitBtnLogin'])) {
$username = trim($_POST['username']);
$password = trim($_POST['password']);
if($username != "" && $password != "") {
try {
$query = "select * from `users` where `username`=:username and `password`=:password";
$stmt = $db->prepare($query);
$stmt->bindParam('username', $username, PDO::PARAM_STR);
$stmt->bindValue('password', $password, PDO::PARAM_STR);
$stmt->execute();
$count = $stmt->rowCount();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if($count == 1 && !empty($row)) {
$_SESSION['sess_user_id'] = $row['id'];
$_SESSION['sess_username'] = $row['username'];
$_SESSION['sess_role'] = $row['role'];
}
if($row['role'] == "role1") {
header('location:modules/role1/index.php');
} else if($row['role'] == "role2") {
header('location:modules/role2/index.php');
} else if($row['role'] == "role3") {
header('location:modules/role3/index.php');
} else if($row['role'] == "role4") {
header('location:modules/role4/index.php');
} else {
$msg = "Invalid login information.";
}
} catch (PDOException $e) {
echo "Error : ".$e->getMessage();
}
} else {
$msg = "Both fields are required.";
}
}
我试着做:
echo($_SESSION['sess_role']);
查看输出是什么,并且它似乎按预期工作,当我在"role1"帐户上时显示"role2",其他角色也是如此。
例如,在访问"role2"面板时,输出仍然是"role1",但我仍然可以输入。
我非常感谢在确定问题方面提供一些帮助。
!
运算符绑定到$_SESSION['sess_role']
,而不是整个表达式。您必须将表达式放在括号if(!($_SESSION['sess_role'] == 'role2'))
中,或者更好地使用not equals运算符以获得更好的可读性if($_SESSION['sess_role'] != 'role2') {
事实证明,根据我留下的评论,失败的原因是:
您应该添加出口;在每个标头之后。您的代码可能希望继续执行。
根据以下问答,建议使用带有exit
的标头;堆栈溢出:
- php-在调用Location:header之后,我应该调用exit()吗
添加注释;不要存储纯文本密码。使用password_hash()
:存储其哈希版本
- http://php.net/manual/en/function.password-hash.php
然后用password_verify()
:进行验证
- http://php.net/manual/en/function.password-verify.php
请通读一遍,这很重要。
仅仅使用事先准备好的语句是不够安全的,尤其是在密码方面。