2017-03-01 81 views
1

我在一个项目中正在进行的工作中,由于信息太多而没有足够的MySQL经验,所以我大量地推翻事物,所以我他们非常希望这里的专家说“闭嘴,做这个。”我甚至开始建议我的整个方法是愚蠢的,应该进行彻底检查。这个项目中唯一不可谈判的事情是使用php和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; 

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

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

所以问题就变成了,用户如何连接他的数据库帐户?我显然不会每次要求他重新输入密码。并且将散列密码保存在$ _SESSION变量中是一个不好的主意,对吧?鉴于此,有没有什么可以在MySQL端进行连接作为更一般的帐户,但将用户设置为自己,以便user()将返回其实际的数据库帐户名称?

或者,正如我在开幕式上所提到的,这种做法是否愚蠢,应该放弃而倾向于更好的做法?感谢您提供的任何信息。

+3

通常,我们的b应用程序使用单个数据库级帐户,并且用户在应用程序级而不是数据库级进行管理。因此用户不必输入他们的用户名和密码来访问数据库。 – Shadow

+1

你正在超越它。并过度构建它。您应该阅读HIPPA或FERPA关于数据库安全性的规定并仅实施其中列出的内容。除此之外的实施是不必要和不安全的。 – Dimi

回答

1

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

你会然后存储在users表用户的数据,你也可以有一个roles/permissions表,该表通过user_permissions/user_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变量认证的事实,并让您的应用程序代码检查该变量看看是否应允许用户保留在“仪表板”上或重定向回登录页面。