Permitir y Denegar

Sidebar 8.5

Porcentaje completado

En este capítulo:

  • Aprenderemos cómo funcionan los callbacks Allow y Deny.
  • Analizaremos el orden en el que se los llama.
  • El sistema de seguridad de Meteor nos permite controlar los cambios en la base de datos sin tener que definir los métodos necesarios para hacerlo.

    Nosotros hemos tenido que definir un método post específico porque necesitamos hacer tareas adicionales, tales como decorar el post con propiedades adicionales y tomar medidas si la URL del post ya existe.

    Por otro lado, tampoco hemos tenido que crear métodos para actualizar y eliminar posts. Solo necesitábamos comprobar si el usuario tenía permiso para hacer la acción, y ha sido muy fácil usando los callbacks allow y deny.

    Usar estos callbacks nos ha permitido ser más declarativos con las modificaciones en la base de datos, definiendo qué tipo de cambios se pueden hacer. El hecho de que estén integrados en el sistema de cuentas es, además, una ventaja añadida.

    Múltiples callbacks

    Podemos definir todos los callbacks allow que queramos. Solo es necesario que, al menos uno de ellos devuelva true, para el cambio actual. De esta forma, cuando se llama a Posts.insert desde un navegador (no importa si es desde el código cliente de nuestra aplicación o desde la consola), el servidor llamará a todos los insert-permitidos que pueda hasta que encuentre uno que devuelva true. Si no encuentra ninguno, no permite la inserción, y se devuelve al cliente un error 403.

    Del mismo modo, podemos definir uno o varios callbacks deny. Si cualquiera de ellos devuelve true, el cambio se cancela y se devuelve un 403. La lógica de todo esto implica que, para que un insert tenga éxito, se ejecutarán uno o varios callbacks allow así como todos los deny.

    Nota: n/e significa No Ejecutado
    Nota: n/e significa No Ejecutado

    En otras palabras, Meteor recorre la lista de callbacks empezando por los deny, y luego ejecuta todos los allow hasta que uno devuelve true.

    Un ejemplo práctico de este patrón podría ser, por ejemplo, tener dos callbacks allow(), uno comprueba si un post pertenece al usuario actual, y otro si el usuario actual es un administrador. Si es un administrador, se asegura que el usuario será capaz de actualizar cualquier post, ya que al menos uno de los callbacks devolverá true.

    Compensación de la latencia

    Recuerda que los métodos que provocan cambios en la base de datos (como .update()) compensan la latencia, igual que cualquier otro método. Así, por ejemplo, si desde la consola del navegador, intentas eliminar un post que no te pertenece, verás que, por un momento, el post desaparece, porque la colección local pierde el documento, pero luego vuelve a aparecer cuando el servidor nos dice que no, que el documento no ha sido eliminado.

    Por supuesto, este comportamiento no es un problema cuando se activa desde la consola (después de todo, si los usuarios juegan con los datos desde la consola, no es problema nuestro lo que ocurra en sus navegadores). Sin embargo, necesitas asegurarte de que esto no sucede desde la interfaz de usuario. Por ejemplo, necesitas tomarte la molestia de asegurar que no muestras a los usuarios botones para eliminar documentos que no están autorizados a borrar.

    Afortunadamente, no suele requerir demasiado código extra poner el código que define los permisos, compartido entre el cliente y el servidor (por ejemplo, podrías escribir una función canDeletePost(user, post) y ponerla en el directorio /lib).

    Permisos en el lado del servidor

    Recuerda que el sistema de permisos solo se aplica a cambios en la base de datos iniciados desde el cliente. En el servidor, Meteor asume que se permiten todas las operaciones.

    Esto significa que si escribes un método DeletePost en el lado del servidor, que puede llamarse desde el cliente, todo el mundo podrá borrar cualquier post. Así que, es probable que no quieras hacer esto, a menos que compruebes los permisos de usuario dentro de ese método.