vista reglas que programacion patrón negocio mvc modelo las implementar encargado diseño controlador consiste arquitectura model-view-controller design authorization playframework

model-view-controller - reglas - patrón de diseño mvc modelo vista controlador



¿Debe la autorización ser parte del modelo o controlador? (6)

Estoy escribiendo una aplicación web con algunos requisitos de ACL: un usuario puede hacer cambios en algunos elementos, algunos pueden ser editables por varios usuarios, el administrador puede editar cualquier cosa y un administrador puede editar todo dentro de su organización, etc.

Estoy usando Play! marco, y por el aspecto del módulo de Secure , parece que el lugar para poner preocupaciones de autorización está en los controladores. Sin embargo, me parece que los problemas de autorización son parte de la lógica comercial y, por lo tanto, deberían estar en el modelo. Además, estoy empezando a ver una lógica duplicada en los controladores que necesito refactorizar.

Por otro lado, agregar autorización al modelo significa que tendría que haber alguna forma de obtener el usuario actual dentro del modelo, lo que no parece correcto. Alternativamente, podría agregar un parámetro "current_user" a cada método de modelo, pero eso parece incluso peor.

Entonces, ¿cuál es la práctica común? ¿Puedo / debo poner código de autorización en el modelo o mantenerlo en el controlador?


Creo que esta es un área gris Se podría argumentar que el acceso de los usuarios es parte del mapeo entre el mundo HTTP y el mundo orientado a objetos. Para eso está diseñado el controlador (de ahí el uso intensivo de estática), para transformar la solicitud entrante, listo para procesar las reglas comerciales en el modelo de dominio.

Sugeriría que la lógica del controlador es absolutamente el lugar correcto para controlar el acceso al modelo, especialmente porque esto se gestiona principalmente en un nivel de anotación, y la autenticación se abstrae a una clase de Seguridad.


Desde mi experiencia personal con MVC frameworks diría:

  1. El modelo es un objeto que representa una tabla de base de datos. Debe ser puro y no debe contener ninguna lógica adicional.
  2. El controlador es el lugar donde se toman las decisiones y otra lógica personalizada, por lo que la autorización debe estar en el controlador. Se podría diseñar un gancho que pueda verificar si el usuario está autorizado o no en todos los lugares necesarios, por lo que no tendrá un código de repetición SECO.

  3. La mejor forma de dar permiso al usuario si está utilizando una arquitectura REST típica es crear un token, guardarlo en el databse y en el lado del cliente y verificar este token en cada solicitud. Si está utilizando una aplicación de navegador web, puede usar sesiones de servidor para la autorización (es mucho más fácil).

Entonces mi propuesta es mantener la lógica de autorización en el Controlador.


En la mayoría de los casos, la seguridad debe ser una (o más) capa por encima del Modelo. La seguridad es un dominio en sí mismo, lo que restringe el acceso a una capa de nivel inferior.

No creo que la seguridad deba hacerse a nivel de controlador.

En mi opinión, esto debería verse así:

Ver -> Controlador -> Seguridad -> Modelo

La capa de seguridad podría ser una fachada o un proxy sobre el modelo, protegiendo el acceso, pero transparente para el controlador.

Sin embargo, si las vistas se van a modificar dependiendo de los derechos de acceso del usuario, es posible que algunas verificaciones tengan que ocurrir en el nivel del controlador (como establecer el valor de una propiedad booleana de CanEdit en el modelo de vista).


Estoy en esta etapa y tengo la intención de manejar esto de la siguiente manera:

  • Sin validación de formulario por JS, en cambio a través de HTTPS ajax

  • Una clase php Ajax

  • Los datos del formulario enviados a un modelo como sus datos para la validación concreta de
    tipo común como el correo electrónico y la contraseña (probablemente la validación de la matriz assoc será reutilizada por otras clases, por lo que definitivamente es un área modelo).

  • si no hay error, una búsqueda en una tabla de usuario para las credenciales correo electrónico /
    credenciales de contraseña pasadas a un controlador con la autenticación
    escriba como inicio de sesión / inicio de sesión / restablecimiento de contraseña

  • el controlador produce la vista de salida requerida o establece el usuario conectado en sesión, etc.

Esto se basa en Laravel, pero tengo mi propia biblioteca ya que la quiero independiente de laravel y simplemente basada en este requisito vital.

El punto es que el Modelo busca las credenciales requeridas como datos, luego las envía al Controlador, ya que no le importa cómo debe procesarse. Creo que esta es la única forma de hacer de esta área una responsabilidad definitiva entre cada uno de los componentes.


La autorización no debe ser parte del controlador o modelo de dominio.

En cambio, debería estar en la capa de servicio.

El controlador solo debe actuar como despachador y delegar entre HTTP y el servicio de aplicación. Es el servicio de aplicaciones donde se lleva a cabo la orquestación. Este es el mejor lugar para colocar la autorización.

Supongamos que el usuario A está autorizado para acceder a los datos del dominio X, pero no está autorizado incluso para un acceso de lectura para los datos del dominio Y. Si la autorización se coloca en el controlador, el usuario A obtiene autorización en el controlador X y, a través de las llamadas de servicio acceder a los datos del dominio Y, que no es lo que esperábamos.

Dado que los modelos de dominio se comunican entre sí en la capa de servicio, por lo tanto, es mejor colocar la autorización en el mismo nivel.


Personalmente, me gusta mucho la forma en que juega! El módulo seguro maneja esto ( el tutorial es siempre útil aquí ). Si no te importa usar la anotación @Before , es bastante sencillo.