-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy path08s-allow-and-deny.md.erb
64 lines (42 loc) · 5.12 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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
---
title: Allow and Deny
slug: allow-and-deny
date: 0008/01/02
number: 8.5
points: 5
sidebar: true
photoUrl: http://www.flickr.com/photos/ikewinski/9475104376/
photoAuthor: Mike Lewinski
contents: Aprenda sobre os callbacks Allow e Deny.|Entenda em que order os callbacks são chamados.
paragraphs: 16
---
O sistema de segurança do Meteor nos permite controlar modificações ao banco de dados sem precisarmos definir Métodos toda vez que nós queremos fazer mudanças.
Por nós necessitarmos fazer tarefas auxiliares como decorar o post com propriedades extras e tomar uma ação especial quando o URL do post já ter sido postada, usar um Método `post` específico fazia bastante sentido ao se criar um post.
Por outro lado, nós não precisamos realmente criar novos Métodos para atualizar e deletar posts. Nós apenas precisamos checar se o usuário tem permissão para fazer tais ações, e isto foi feito pelas callbacks `allow` e `deny`.
Usar estas callbacks nos permite sermos mais declarativos quanto às modificações ao banco de dados, e dizer que tipo de atualizações podem ser feitas. O fato delas se integrarem ao sistema de contas é um bônus adicional.
### Callbacks múltiplas
Nós podemos definir quantas callbacks `allow` quanto necessárias. Nós precisamos que _pelo menos uma_ delas retorne `true` para a dada mudança que está ocorrendo. Então quando `Posts.insert` é chamado no navegador (não importa se é do código do aplicativo do lado do cliente ou do console), o servidor irá em resposta chamar quaisquer checagens de `insert` permitidas que ele puder até encontrar uma que retorne true. Se ele não encontrar nenhuma, ele não permitirá o insert, e retornará um erro `403` para o cliente.
Similarmente, nós podemos definir uma ou mais callbacks `deny`. Se _qualquer uma_ dessas callbacks retornar `true`, a mudança será cancelada e um `403` será retornado. A lógica disto significa que para um `insert`bem-sucedido, uma ou mais callback `allow` `insert` assim como _cada_ callback `deny` `insert` serão executadas.
<%= diagram "allow_deny", "Note: n/e stands for Not Executed" %>
Em outras palavras, Meteor começa a lista de callback primeiro com `deny`, então com `allow`, e executa cada callback até que uma delas retorne `true`.
Um exemplo prático deste padrão poderia ser ter duas callbacks `allow()`, uma que checa se o post pertence ao usuário atual, e a segunda que checa se o usuário atual tem direitos administrativos. Se o usuário atual é um administrador, isto garante que ele poderá atualizar qualquer post, já que pelo menos uma dessas callbacks retornará true.
### Compensação de Latência
Lembre que Métodos de mutação do banco de dados (tais como `.update()`) tem sua latência compensada, assim como qualquer outro Método. Por exemplo, se você tentar deletar um post que não pertence a você através do console, você verá que o post brevemente desaparece ao passo que sua coleção local perde o documento, mas então re-aparece assim que o servidor informa que, não, de fato o documento não foi deletado.
Claro que este comportamento não é um problema quando acionado pelo console (até mesmo porque se os usuários estiverem tentando bagunçar com informação no console, não é realmente um problema seu o que acontece no navegador _deles_). Entretanto, você precisa assegurar que isto não aconteça na sua interface do usuário. Por exemplo, você precisa tomar cuidado para assegurar que você não está mostrando aos usuários botões de deletar para documentos que eles não têm permissão para tanto.
Felizmente, já que você pode compartilhar código de permissão entre o cliente e o servidor (por exemplo, você poderia escrever uma função de biblioteca `canDeletePost(user, post)` e pô-la no diretório compartilhado `/lib`), fazer isto normalmente não requer muito código extra.
### Permissões do lado do servidor
Lembre que o sistema de permissões se refere apenas às mutações do banco de dados iniciadas no cliente. No servidor, o Meteor assume que _todas_ operações são permitidas.
Isto signfica que se você tivesse que escrever um Método Meteor `deletePost` do lado do servidor que pudesse ser chamado do cliente, qualquer um seria capaz de deletar qualquer post. Então você provavelmente não quer fazer isso a não ser que você cheque as permissões do usuário dentro do Método também.
### Usando Deny como uma Callback
Finalmente, um truque que você pode fazer com `deny` é usá-la como uma callbaclk "onX". Por exemplo, você pode conseguir uma timestamp `lastModified` com o código seguinte:
~~~js
Posts.deny({
update: function(userId, doc, fields, modifier) {
doc.lastModified = +(new Date());
return false;
},
transform: null
});
~~~
Como callbacks `deny` rodam para *cada* `update` bem-sucedido, nós sabemos que essa callback rodará e poderá fazer mudanças ao documento de uma forma estruturada.
Admitidamente, esta técnica é tipo um hack, então você pode querer fazer atualizações usando um Método no lugar. De qualquer forma, ainda é bom saber, e no futuro nós podemos esperar que algum tipo de callback `beforeUpdate` esteja disponível.