1

我正处于一个我正在从事的项目中,由于信息过多且没有足够的 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;

由于每个用户都有自己的数据库帐户,其中绝大多数用户只能选择、更新、插入等相关视图,这完美地为我提供了用户工作的组织,用户组织的直属子组织,以及属于上述任何组织的任何系统。用户名是他们的电子邮件地址,因此 user 函数的 substring_index 中的 2 是他们的密码,并且他们的密码已充分散列。

当我添加 Web 界面时,问题就出现了。显然,当用户使用他们的用户名和密码登录时,这些将通过 mysqli_connect() 传递给数据库。据我所知,最佳实践是在每个事务或事务组运行后关闭连接。

那么问题就变成了,用户如何在他的数据库账号下进行连接呢?我显然不会要求他每次都重新输入密码。将散列密码保存在 $_SESSION 变量中是个坏主意,对吧?鉴于此,是否可以在 MySQL 端做一些事情来连接为更通用的帐户,但将用户设置为他自己,这样 user() 将返回他的实际数据库帐户名称?

或者,正如我在开头所问的那样,这种方法是不是很愚蠢,应该被废弃以支持更好的做法?感谢您提供的任何信息。

4

1 回答 1

1

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

然后,您将用户的数据存储在一个users表中,您还可以有一个roles/表,它通过/permissions表连接到每个用户。user_permissionsuser_roles

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

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

<?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!!";
}

?>

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

于 2017-03-01T15:36:52.873 回答