假設您有具有外鍵關系的 SQL 表。
用戶:id, has_many posts
帖子:id,has_many 段落
段落:id,字串文本
也許您有 SQL 查詢來按帖子的 ID 查看帖子或按段落的 ID 查看段落。或者您的 SQL 模式可能比這更復雜,但具有特定 ID 的用戶仍然清楚地擁有資源。
給定用戶 ID,SQL 中是否有任何方法可以驗證 SQL 讀寫只能針對該用戶 ID“擁有”的資源進行。您可以想象撰寫如下函式:
validateUserForPostId(postID, userID):
IF CreateSQLQuery("SELECT parent.ID FROM posts child JOIN on users on parent.ID = child.userID WHERE child.ID = ?", postID) == userID:
return true; // Valid, so we should be able to read or write post with ID = postID
validateUserForParagraphId(paragraphID):
// Similar join logic
您可以想象 SQL 模式會變得非常復雜,并且撰寫起來真的很煩人。是否有內置的 SQL 解決方案?我現在正在使用 SQLite,但通用解決方案也適用。
uj5u.com熱心網友回復:
在回答之前,我們需要弄清楚一件事:sqllite這里(或任何其他潛在的資料庫引擎)并不知道表中的資料是用戶、所有權等。從您的資料庫引擎的角度來看,這些是位元組,而且只是位元組。
如果您試圖在資料庫引擎端解決該問題,唯一的方法是JOIN針對每個查詢的所有權表并過濾掉資料。例如,如果您正在嘗試閱讀一篇文章,而不是:
select
content, timestamp, userID
from
posts
您需要將具有當前用戶 ID 的引數傳遞到查詢中以最小化檢查:
select
posts.content,
posts.timestamp,
posts.userID
from
posts child
join users on parent.ID = child.userID
where
parent.ID = '?'
and child.ID = '?'
一種使其更易于管理的流行解決方案是使用存盤程序之類的東西(很多資料庫引擎都支持它們)。它變成了這樣的:
EXEC sp_getPost “postID”, “userID”
另一種方法是在資料庫引擎端創建視圖,執行必要的連接并始終公開一致的列名(如authorUserId)以進行過濾。
但是,對于大型現代應用程式或服務,通常在應用程式代碼中解決它,而不是在資料庫端。
uj5u.com熱心網友回復:
如果用戶已登錄,則通常會涉及他們在計算機和服務器之間建立會話。服務器可以將會話變數分配給每個用戶特定的每個會話。用戶看不到這些變數。
如果您在用戶登錄時將用戶的 ID (uid) 分配給會話變數,那么對于您構建的任何 SQL 查詢,您都可以在 WHERE 條件中使用它。例如:
SELECT name, hair_color, etc FROM my_table WHERE uid = :uid
這里的 :uid 表示 uid 會話變數。
實作細節特定于每種語言,但我認為這是使所有用戶的資料僅供該用戶使用且僅在他們登錄站點時可用的常用方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/535529.html
標籤:数据库sqlite验证
下一篇:lower()在None上被呼叫
