2017-03-01 35 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變量認證的事實,並讓您的應用程序代碼檢查該變量看看是否應允許用戶保留在「儀表板」上或重定向回登錄頁面。