我有2个级别的身份验证用户。
在第一层中,我只有用户名和密码,在第二层中,我具有用户的访问角色。
问题是,
有一个用户的数据存在于第一个表中但不存在于第二个表中的机会,即访问表尝试登录。
我没有第二个表中第一个表的所有用户的副本。
有什么办法可以检查用户是否在查询的第二个表中?
现在我的查询是
$roleQuery= " SELECT role FROM accesscredentials WHERE jid=".$_POST['username'];
$roleArray=mysqli_query($con,$roleQuery);
$roleVal = mysqli_fetch_object($roleArray);
$role=$roleVal->role;
当用户尝试登录时,由于他们的名字不在第二个表中,所以我收到一条错误消息: “试图获取非对象的属性'角色'
您能帮我吗? 谢谢 :) 欢呼
答案 0 :(得分:2)
返回一个具有字符串属性的对象,该对象对应于获取的行;如果结果集中没有更多的行,则返回NULL。
因此您可以检查以下内容:
if (is_null($roleVal)) {
$role = "not set.";
}
else {
$role = $roleVal->role;
}
请使用prepared statements保护查询免受SQL攻击。
Qirel建议的替代方案如下所示:
if ($roleArray->num_rows > 0) {
$roleVal = mysqli_fetch_object($roleArray);
$role=$roleVal->role;
}
else {
$role = "not set.";
}
任何人都可以做。但是,要使用准备好的语句来完成此操作,您必须:
// sanatize input before anything else
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
// perform prepared query
$roleQuery = "SELECT role FROM accesscredentials WHERE jid=?";
$roleStatement = $con->prepare($roleQuery);
$roleStatement->bind_param("s", $username);
$roleStatement->bind_result($role);
$roleStatement->execute();
// fill role with something when not found
if (!$roleStatement->fetch()) {
$role = "not set.";
}
// now you can use $role
答案 1 :(得分:2)
您有两个问题和一个漏洞。可以使用准备好的语句来修复此漏洞,但这也可以解决您的第一个问题-必须在查询中使用字符串值$_POST['username']
。
最后,您必须先检查是否有要获取的行,然后才能真正使用这些值。
$roleQuery= " SELECT role FROM accesscredentials WHERE jid=?";
$stmt = $con->prepare($roleQuery);
$stmt->bind_param("s", $_POST['username']);
$stmt->bind_result($role);
$stmt->execute();
if ($stmt->fetch()) {
echo "Role was ".$role;
}
答案 2 :(得分:2)
在某些情况下,我是try/catch
块的忠实拥护者,在我看来,这就像一个这样的用例场景。通过使用prepared statement
,您(实际上)消除了SQL注入攻击的可能性,并消除了不引用sql中的字符串(该值大概是数字)的可能错误。
使用try / catch意味着您可以提出自己有用的调试消息来帮助调试逻辑,而无需诉诸使用mysqli_error()
等,这在许多情况下显示得太多了。
希望这对您有用
try{
$sql='select `role` from `accesscredentials` where `jid`=?';
$stmt=$con->prepare( $sql );
if( $stmt ){
$username=filter_input( INPUT_POST, 'username', FILTER_SANITIZE_STRING );
if( $username ){
$stmt->bind_param('s',$username );
$status=$stmt->execute();
if( $status && $stmt->num_rows==1 ){
$stmt->store_result();
$stmt->bind_result( $role );
$stmt->fetch();
$stmt->free_result();
$stmt->close();
/* $role is available as a variable */
echo $role;
} else {
throw new Exception( $stmt->num_rows==0 ? 'Query failed or there are no records' : 'Error' );
}
} else {
throw new Exception('No valid username');
}
} else {
throw new Exception('Failed to prepare "SELECT" query');
}
}catch( Exception $e ){
exit( $e->getMessage() );
}
答案 3 :(得分:0)
尝试一下
$roleQuery= "SELECT role FROM accesscredentials WHERE jid=".$_POST['username'];
if ($result=mysqli_query($con,$roleQuery))
{
while ($obj=mysqli_fetch_object($result))
{
echo $obj->role;
}
// Free result set
mysqli_free_result($result);
}