Php 从查询结果设置会话变量
我一直在修改一个用户身份验证系统,但在为管理员设置会话时遇到了问题。Php 从查询结果设置会话变量,php,mysql,Php,Mysql,我一直在修改一个用户身份验证系统,但在为管理员设置会话时遇到了问题。reguser会话的设置很好,但我不明白为什么admin不会设置 userlevel为9的用户是管理员。是的,我知道如何防止SQL注入。我现在只是想让它保持简单易读。这可能不会用于任何事情,我只是获得了一些PHP的经验 大家好,谢谢你们的帮助!我让它工作了。我盯着它看了太久,脑子都不清楚了。昨天休息了一会儿,今天又回来了,在不到5分钟的时间里就搞定了!你们太棒了,我爱你们 function checklogin($email,
reguser
会话的设置很好,但我不明白为什么admin
不会设置
userlevel
为9的用户是管理员。是的,我知道如何防止SQL注入。我现在只是想让它保持简单易读。这可能不会用于任何事情,我只是获得了一些PHP的经验
大家好,谢谢你们的帮助!我让它工作了。我盯着它看了太久,脑子都不清楚了。昨天休息了一会儿,今天又回来了,在不到5分钟的时间里就搞定了!你们太棒了,我爱你们
function checklogin($email, $pass) {
$server = 'localhost';
$user = 'root';
$password = '';
$connection = mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db(udogoo, $connection) or die(mysql_error());
$pass = md5($pass);
$result = mysql_query("SELECT userid from users WHERE email = '$email' AND password = '$pass'");
$user_data = mysql_fetch_array($result);
$no_rows = mysql_num_rows($result);
if ($no_rows == 1)
{
$_SESSION['reguser'] = true;
$_SESSION['userid'] = $user_data['userid'];
$userid = $user_data['userid'];
$isadmin = mysql_query("SELECT userlevel FROM users WHERE userid = '$userid'");
$isadmin2 = mysql_fetch_array($isadmin);
$isadmin3 = $isadmin2['userlevel'];
if ($isadmin3 == "9"){
$_SESSION['admin'] = true;
return true;
}
}
else
{
return FALSE;
}
}
因此,您的完整代码如下所示:
<?php
function checklogin($email, $pass)
{
$server = 'localhost';
$user = 'root';
$password = '';
$connection = mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db(test, $connection) or die(mysql_error());
$pass = md5($pass);
$result = mysql_query("SELECT userid from users WHERE email = '$email' AND password = '$pass'");
$user_data = mysql_fetch_array($result);
$numrows = mysql_num_rows($result);
if ($numrows == 1)
{
$_SESSION['reguser'] = true;
$_SESSION['userid'] = $user_data['userid'];
//MY ANSWER START HERE
$userid = $_SESSION['userid'];
$isadmin = mysql_query("SELECT userlevel FROM users WHERE userid = $userid");
$user_data = mysql_fetch_array($result);
$userlevel = $user_data['userlevel'];
if($userlevel == '9')
{
$_SESSION['admin'] = true;
}
//END HERE
}
else
{
return false;
}
}
?>
您有一个返回true代码>如果用户数据存在。事实上,只有当用户不存在时,才能检查或管理属性
删除返回true的选项代码>,因为那里不需要它。如果需要,添加否则返回false
检查用户是否存在后,返回true代码>就在末尾。您的逻辑也有缺陷,如下所示:
function checklogin($email, $pass)
{
$server = 'localhost';
$user = 'root';
$password = '';
$connection = mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db(test, $connection) or die(mysql_error());
$email = mysql_real_escape_string($email);
$pass = md5($pass);
$sql = "SELECT `userid`,`userlevel`
FROM `users`
WHERE `email` = '$email'
AND `password` = '$pass'
LIMIT 1"; //I certainly hope you check email for injection before passing it here. Also want the LIMIT 1 on there because you are only expecting a single return, and you should only get one since `email` should be unique since you're using it as a credential, and this will stop it from looking through all the rows for another match once it finds the one that matches.
$result = mysql_query($sql);
$user_data = mysql_fetch_array($result);
$numrows = mysql_num_rows($result);
if ($numrows == 1)
{
$_SESSION['reguser'] = true;
$_SESSION['userid'] = $user_data['userid'];
if($user_data['userlevel'] == 9)
{
$_SESSION['admin'] = true;
}
else
{
$_SESSION['admin'] = false;
}
return true;
}
return false;
}
这应该行得通。当一个查询可以很好地完成时,没有很好的理由进行两个查询。如果用户已登录,则返回true;如果用户不存在或凭据不匹配,则返回false
Oops,SQL语句中的小语法错误,已更正。更大的语法错误也被纠正了
以下是您如何在PDO中完成顶部部分:
function checklogin($email, $pass)
{
$server = 'localhost';
$user = 'root';
$password = '';
$dbname = 'test';
$dsn = 'mysql:dbname=' . $dbname . ';host=' . $server;
$conn = new PDO($dsn,$user,$password); //Establish connection
$pass = md5($pass);
$sql = "SELECT `userid`,`userlevel`
FROM `users`
WHERE `email` = :email
AND `password` = :pass
LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':email',$email,PDO::PARAM_STR,128) //First param gives the placeholder from the query, second is the variable to bind into that place holder, third gives data type, fourth is max length
$stmt->bindParam(':pass',$pass,PDO::PARAM_STR,32) //MD5s should always have a length of 32
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute(); //almost equivalent to mysql_query
$user_data = $stmt->fetch(); //Grab the data
if(is_array($user_data) && count($user_data) == 2) //Check that returned info is an array and that we have both `userid` and `userlevel`
{
//Continue onwards
我以前也尝试过类似的方法,但没有效果。奇怪的是,它与“reguser”会话的设置方式几乎完全相同。用户id
可能是字母数字字段,因此可能需要是“$userid”
。但这似乎解决了使用$result
进行搜索的明显错误。@JaredFarrish,谢谢你纠正我的答案。是的,你是对的。只是一个旁白,但是如果$\u SESSION['userid']
设置正确,你可以使用它而不是函数范围的变量……不过,请注意@Kolink的回答,它讨论了函数在到达有效用户之前短路的事实。返回TRUE
也需要显示出来。首先,$result
是一个,因此您在选择用户级别中包含它…
实际上并不是按照您认为的用户ID进行搜索。它可能在搜索资源ID 35; XX
或其他东西。与其使用普通的md5()
值作为密码,不如使用CRYPT\u BLOWFISH
散列类型和salt值,这使得存储密码更加安全。是的,这是另一个问题。好主意。你可以演示如何逃逸电子邮件地址(尽管OP确实提到了在电子邮件中逃逸)。注意,转义只是一种良好的实践,不一定是一种安全实践。事实上,由于这是一封电子邮件,只需检查它的有效电子邮件格式就足够了。想不到任何SQL注入都适合这种格式xxx@xxx.xxx或xxx@xxx.xx.xx. 对我来说,我只是确保我的输入符合他们的要求,并使用PDO和准备好的语句和绑定参数,不再担心它。这是一些不同寻常的建议。由于示例和您的答案不使用PDO,因此转义是一个事实要求。尽管进行了验证,但在大多数情况下查询中的输入都应该转义。我刚刚意识到:用户在查询中缺少。@Jared Farrish修复了用户的。他没有使用PDO,所以我没有在PDO中使用它,所以我注意到它应该被转义。当使用准备好的语句和绑定参数时,PDO将转义输入并检查其数据类型的有效性。如果他的问题是“如何转义mysql_查询输入”,那么我将讨论如何转义它。
function checklogin($email, $pass)
{
$server = 'localhost';
$user = 'root';
$password = '';
$dbname = 'test';
$dsn = 'mysql:dbname=' . $dbname . ';host=' . $server;
$conn = new PDO($dsn,$user,$password); //Establish connection
$pass = md5($pass);
$sql = "SELECT `userid`,`userlevel`
FROM `users`
WHERE `email` = :email
AND `password` = :pass
LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':email',$email,PDO::PARAM_STR,128) //First param gives the placeholder from the query, second is the variable to bind into that place holder, third gives data type, fourth is max length
$stmt->bindParam(':pass',$pass,PDO::PARAM_STR,32) //MD5s should always have a length of 32
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute(); //almost equivalent to mysql_query
$user_data = $stmt->fetch(); //Grab the data
if(is_array($user_data) && count($user_data) == 2) //Check that returned info is an array and that we have both `userid` and `userlevel`
{
//Continue onwards