-
Notifications
You must be signed in to change notification settings - Fork 30
/
08s-allow-and-deny.md.erb
46 lines (29 loc) · 4.14 KB
/
08s-allow-and-deny.md.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
---
title: Permitir y Denegar
slug: allow-and-deny
date: 0008/01/02
number: 8.5
points: 10
sidebar: true
photoUrl: http://www.flickr.com/photos/ikewinski/9475104376/
photoAuthor: Mike Lewinski
contents: Aprenderemos cómo funcionan los callbacks Allow y Deny.|Analizaremos el orden en el que se los llama.
paragraphs: 16
---
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`.
<%= diagram "allow_deny", "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.