С большими сайтами у меня работали, права доступа определялись на уровне приложения. База данных связала контент с записью пользователя, после чего на уровне доступа к данным / бизнес-логики было принято решение, достаточно ли у пользователя прав для доступа к контенту.
Для большого сайта с динамическим контентом я думаю, что это, вероятно, лучший способ справиться с этим.
РЕДАКТИРОВАТЬ: Чтобы добавить более конкретный пример.
Пример:
Хорошо, допустим, у нас есть простой сайт для хранения файлов, где пользователь может получить доступ только к своим данным или данным, которые были явно переданы им другим пользователем.
Поскольку это приложение довольно простое, поскольку оно просто обслуживает файлы, оно имеет только три таблицы базы данных:
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
Теперь некоторые основные правила, которые мы захотим определить на нашем уровне доступа к данным, заключаются в том, что, когда пользователь вошел в систему, он может получить доступ к файлам, владельцем которых он является, и к файлам, которыми другие пользователи поделились с ним. Таким образом, либо с помощью хранимых процедур, либо создав запрос для отправки на сервер базы данных, я бы удостоверился, что мои запросы возвращают только те записи, к которым у них есть доступ.
Вот базовый SQL-запрос GetUsersFileList, когда пользователь входит в систему:
SELECT FileId, FileName, FileType
FROM Files
WHERE FileOwnerId = @UserId
Как вы можете видеть здесь, мы используем параметризованный запрос для получения файлов, владельцем которых является пользователь. Кроме того, мы будем запрашивать общие файлы, а также отображать их для пользователя.
Теперь, если мы предположим, что у каждого файла будет свой уникальный URL, например:
http://mydomain.com/filehandler.php?fileId=123546
Затем, когда мы пытаемся получить файл, мы используем запрос, аналогичный приведенному выше, чтобы попытаться получить данные файла:
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)
Итак, вы видите, что когда мы пытаемся получить файл, мы все еще используем UserId в запросе, таким образом, если у пользователя нет файла, к которому он был предоставлен, или он не является владельцем файла, результат запроса будет быть 0 строк.
Таким образом, разрешения определяются тем, что пользователь отображает в базе данных, но фактическое применение осуществляется путем тщательного написания вашего кода доступа к данным и / или дополнительных проверок на уровне бизнес-логики перед подачей контента.
EDIT2: я больше всего знаком с MSSQL, поэтому мои запросы выше относятся к T-SQL, поэтому синтаксис для MySql может быть немного невелик.
EDIT3: заменен уровень бизнес-логики уровнем доступа к данным, поскольку в этом примере выполняются только проверки внутри самих запросов доступа к данным.
EDIT4: Хорошо, вернемся к уровню бизнес-логики, поскольку более сложным приложениям потребуются более сложные схемы разрешений, что может потребовать дополнительных проверок на уровне бизнес-логики.