En mi experiencia, la verdadera pregunta se reduce principalmente a si se va a producir o no alguna cantidad de restricción de acceso específica del usuario.
Suponga, por ejemplo, que está diseñando el esquema de una comunidad y que permite a los usuarios alternar la visibilidad de su perfil.
Una opción es apegarse a un indicador de perfil público/privado y apegarse a verificaciones de permisos amplias y preventivas:'users.view' (vistas de usuarios públicos) vs, digamos, 'users.view_all' (vistas a todos los usuarios, para moderadores) .
Otro implica permisos más refinados, es posible que desee que puedan configurar cosas para que puedan ser (a) visibles para todos, (b) visibles para sus amigos seleccionados a mano, (c) mantenidos en privado por completo, y tal vez (d ) visible para todos, excepto para sus bozos seleccionados a mano. En este caso, debe almacenar datos relacionados con el propietario/acceso para filas individuales, y deberá abstraer en gran medida algunas de estas cosas para evitar materializar el cierre transitivo de un gráfico denso y orientado.
Con cualquiera de los dos enfoques, descubrí que la complejidad adicional en la edición/asignación de roles se compensa con la facilidad/flexibilidad resultante en asignar permisos a datos individuales y que lo siguiente funcionó mejor:
- Los usuarios pueden tener varios roles
- Roles y permisos combinados en la misma tabla con una bandera para distinguirlos (útil al editar roles/permisos)
- Los roles pueden asignar otros roles, y los roles y permisos pueden asignar permisos (pero los permisos no pueden asignar roles), desde dentro de la misma tabla.
El gráfico orientado resultante se puede extraer en dos consultas, generar de una vez por todas en un período de tiempo razonable utilizando el idioma que esté utilizando y almacenar en caché en Memcache o similar para su uso posterior.
A partir de ahí, obtener los permisos de un usuario es cuestión de verificar qué roles tiene y procesarlos usando el gráfico de permisos para obtener los permisos finales. Verifique los permisos verificando que un usuario tenga el rol/permiso especificado o no. Y luego ejecute su consulta/emita un error basado en esa verificación de permisos.
Puede ampliar la comprobación de nodos individuales (es decir, check_perms($user, 'users.edit', $node)
para "puede editar este nodo" frente a check_perms($user, 'users.edit')
para "puede editar un nodo") si lo necesita, y tendrá algo muy flexible/fácil de usar para los usuarios finales.
Como debería ilustrar el ejemplo de apertura, tenga cuidado de orientarse demasiado hacia los permisos de nivel de fila. El cuello de botella de rendimiento es menor al verificar los permisos de un nodo individual que al obtener una lista de nodos válidos (es decir, solo aquellos que el usuario puede ver o editar). No recomendaría nada más allá de las banderas y los campos de ID de usuario dentro de las filas si no está (muy) bien versado en la optimización de consultas.