在实现行级安全的同时,通过PHP登录MySQL数据库帐户

在实现行级安全的同时,通过PHP登录MySQL数据库帐户,php,mysql,row-level-security,Php,Mysql,Row Level Security,我正在做一个项目,由于MySQL的信息太多,经验太少,我的想法太多了,所以我非常希望这里的专家说“闭嘴,做这个。”我甚至愿意接受这样的建议,我的整个方法都是愚蠢的,应该彻底改变。在这个项目中,唯一不可协商的就是php和MySQL的使用 所以我尝试在MySQL中实现行级安全性。阅读一些好文章,解释MySQL没有角色,因此您需要为需要FGAC的每个表使用一个视图,或者在其中过滤用户标识信息(如用户ID)的条件。由于数据库的相对复杂性和数据库性质的安全性问题,我选择了视图路由。下面是我的一个视图示例:

我正在做一个项目,由于MySQL的信息太多,经验太少,我的想法太多了,所以我非常希望这里的专家说“闭嘴,做这个。”我甚至愿意接受这样的建议,我的整个方法都是愚蠢的,应该彻底改变。在这个项目中,唯一不可协商的就是php和MySQL的使用

所以我尝试在MySQL中实现行级安全性。阅读一些好文章,解释MySQL没有角色,因此您需要为需要FGAC的每个表使用一个视图,或者在其中过滤用户标识信息(如用户ID)的条件。由于数据库的相对复杂性和数据库性质的安全性问题,我选择了视图路由。下面是我的一个视图示例:

create OR replace view v_system_requirement (
 sys_id,
 req_id, 
 sysreq_notes,
 rate_id,
 range_id,
 art_id,
)
as
select
  system_requirement.org_id,
  organization.org_name,
  organization.org_parent_branch,
  system.sys_id,
  system.sys_name
from organization JOIN system USING (org_id)
where
  organization.org_id IN 
    (select o.org_id from organization o JOIN user u ON o.org_parent_branch=u.org_id OR o.org_id=u.org_id WHERE u.user_email=substring_index(user(), '@', 2)
);

select * from v_user_reference;
由于每个用户都有自己的数据库帐户,绝大多数用户只能选择、更新、插入等相关视图,这就完美地为我提供了用户工作的组织、用户组织的直接子组织以及属于上述任何组织的任何系统。用户名是他们的电子邮件地址,因此在用户函数的子字符串_索引中是2,并且他们的密码经过了充分的哈希处理

当我添加web界面时,这里的麻烦就来了。显然,当用户使用用户名和密码登录时,这些信息将通过mysqli_connect()传递到数据库。据我所知,最佳做法是在运行每个事务或事务组后关闭连接

所以问题变成了,用户如何在他的数据库帐户下连接?很明显,我不会每次都要求他重新输入密码。将散列密码保存在$会话变量中是个坏主意,对吗?考虑到这一点,在MySQL端是否可以做一些事情来连接为一个更通用的帐户,但将用户设置为自己,以便user()返回其实际的数据库帐户名


或者,正如我在开场白中所问的那样,这种方法是愚蠢的,应该为了更好的实践而放弃吗?感谢您提供的所有信息。

通常,在PHP/MySQL应用程序中,应用程序有一个帐户来访问数据库。这将存储在某种类型的配置文件或创建数据库连接的类中

然后将用户的数据存储在
用户
表中,还可以有一个
角色
/
权限
表,该表通过
用户权限
/
用户角色
表连接到每个用户

通过这种方式,您可以让用户登录并通过将其凭据与数据库中的行相匹配的方式进行身份验证,并且您可以管理他们拥有的权限,而不必担心他们在登录数据库时总是键入密码,因为应用程序登录数据库而不是用户

使用教程作为基础,它看起来像这样:

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// prepare and bind
$stmt = $conn->prepare("SELECT * FROM users WHERE email = ?");
$stmt->bind_param("s", $_POST['email']);
$stmt->execute();

$user = $stmt->fetch_assoc();

if(password_verify($_POST['password'], $user['password']))
{
    echo "User authenticated";
}
else 
{
    echo "DENIED!!";
}

?>


然后,您可以将用户已通过身份验证的事实存储在
$\u会话
变量中,并让应用程序代码检查该变量,以查看是否应允许用户保留在“仪表板”上或者被重定向回登录页面。

通常我们b应用程序使用单个数据库级别的帐户,用户在应用程序级别而不是数据库级别进行管理。因此,用户无需输入用户名和密码即可访问数据库。你想得太多了。而且建得太多了。您应该阅读HIPPA或FERPA关于数据库安全性的法规,并只实施其中列出的内容。实现更多的功能是不必要的,也是不安全的。