所以我使用cakephp创建一个小站点,并且我的ACL被设置为每次创建一段内容时,创建一个ACL规则以将该段内容的所有者链接到实际内容.这允许每个所有者编辑/删除他们自己的内容.这种方法看起来效率很低,因为数据库中的内容存在等量的ACL规则.我很好奇,拥有数百万条内容的大型网站如何解决这个问题?
Adr*_*ian 10
对于大型站点,我在应用程序级别确定了访问权限.数据库将内容与用户的记录相关联,然后在数据访问/业务逻辑层中确定用户是否具有访问内容的足够权限.
对于具有动态内容的大型网站,我认为这可能是处理它的最佳方式.
编辑:添加一个更具体的例子.
示例:Ok说我们有一个简单的文件存储站点,用户只能访问其他用户明确与他们共享的数据或数据.
由于这个应用程序非常简单,因为它只提供文件,因此它只有三个数据库表:
Users Table which has columns:
UserId <int> PK
UserName <varchar>
HashedPassword <varchar>
Files Table which has columns:
FileId <int> PK
FileOwnerId <int> FK (this has a foreign key relationship with UserId in the users table)
FileName <varchar>
MimeType <varchar>
FileData <blob>
SharedFile reference table which has columns:
SharedFileIndex <int> PK
FileId <int> FK
UserId <int> FK
Run Code Online (Sandbox Code Playgroud)
现在,我们要在数据访问层中定义的一些基本规则是,当用户登录时,他们可以访问他们是其所有者的文件以及其他用户与他们共享的文件.因此,无论是通过存储过程还是构建查询以发送到数据库服务器,我都会确保我的查询只返回他们有权访问的那些记录.
这里是用户登录时的基本GetUsersFileList sql查询:
SELECT FileId, FileName, FileType
FROM Files
WHERE FileOwnerId = @UserId
Run Code Online (Sandbox Code Playgroud)
正如您在此处所见,我们使用参数化查询来获取用户所属的文件.此外,我们还会查询共享文件以及向用户显示.
现在,如果我们假设每个文件都有自己独特的URL,例如:
http://mydomain.com/filehandler.php?fileId=123546
Run Code Online (Sandbox Code Playgroud)
然后当我们尝试获取文件时,我们使用与上面类似的查询来尝试获取文件数据:
SELECT FileName, FileType, FileData
FROM Files
LEFT OUTER JOIN SharedFiles on Files.FileId = SharedFiles.FileId
WHERE Files.FileId = @FileId AND (FileOwnerId = @UserId OR SharedFiles.UserId = @UserId)
Run Code Online (Sandbox Code Playgroud)
因此,当我们尝试获取文件时,我们仍然在查询中使用UserId,因此如果用户没有与他们共享文件或者他们不是文件的所有者,则查询结果将为0行.
因此,权限取决于用户在数据库中映射到的内容,但实际执行是通过在提供内容之前仔细编写业务逻辑层中的数据访问代码和/或其他检查来完成的.
EDIT2:我最熟悉MSSQL,所以我上面的查询都是在T-SQL中,所以MySql的语法可能有些偏差.
EDIT3:用数据访问层替换了业务逻辑层,如本例中所做的唯一检查是在数据访问查询本身内.
EDIT4:Ok回过头参考业务逻辑层,因为更复杂的应用需要更复杂的权限方案,这可能需要在业务逻辑层进行额外的检查.