/
attribute-requires.texy
179 lines (130 loc) · 5.85 KB
/
attribute-requires.texy
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
Como usar o `#[Requires]` Atributo
**********************************
.[perex]
Ao escrever um aplicativo da Web, você frequentemente se depara com a necessidade de restringir o acesso a determinadas partes do aplicativo. Talvez você queira que algumas solicitações só possam enviar dados por meio de um formulário (usando, portanto, o método POST) ou que sejam acessíveis somente a chamadas AJAX. No Nette Framework 3.2, foi introduzida uma nova ferramenta que permite que você defina essas restrições de forma elegante e clara: o atributo `#[Requires]` atributo.
O atributo é um marcador especial no PHP, que você adiciona antes da definição de uma classe ou método. Como ele é essencialmente uma classe, você precisa incluir a cláusula use para que os exemplos a seguir funcionem:
```php
use Nette\Application\Attributes\Requires;
```
Você pode usar o atributo `#[Requires]` com a própria classe do apresentador e nesses métodos:
- `action<Action>()`
- `render<View>()`
- `handle<Signal>()`
- `createComponent<Name>()`
Os dois últimos métodos também se referem a componentes, portanto, você também pode usar o atributo com eles.
Se as condições especificadas pelo atributo não forem atendidas, será acionado um erro HTTP 4xx.
Métodos HTTP .[#toc-http-methods]
---------------------------------
Você pode especificar quais métodos HTTP (como GET, POST, etc.) são permitidos para acesso. Por exemplo, se você quiser permitir o acesso somente por meio do envio de um formulário, defina:
```php
class AdminPresenter extends Nette\Application\UI\Presenter
{
#[Requires(methods: 'POST')]
public function actionDelete(int $id): void
{
}
}
```
Por que você deve usar POST em vez de GET para ações de alteração de estado e como fazer isso? [Leia o guia |post-links].
Você pode especificar um método ou uma matriz de métodos. Um caso especial é o valor `'*'` para ativar todos os métodos, que os apresentadores não permitem por padrão por [motivos de segurança |application:presenters#http-method-check].
Chamadas AJAX .[#toc-ajax-calls]
--------------------------------
Se você quiser que um apresentador ou método seja acessível somente para solicitações AJAX, use:
```php
#[Requires(ajax: true)]
class AjaxPresenter extends Nette\Application\UI\Presenter
{
}
```
Mesma origem .[#toc-same-origin]
--------------------------------
Para aumentar a segurança, você pode exigir que a solicitação seja feita a partir do mesmo domínio. Isso evita a [vulnerabilidade ao CSRF |nette:vulnerability-protection#cross-site-request-forgery-csrf]:
```php
#[Requires(sameOrigin: true)]
class SecurePresenter extends Nette\Application\UI\Presenter
{
}
```
Para os métodos `handle<Signal>()` o acesso do mesmo domínio é automaticamente necessário. Portanto, se você quiser permitir o acesso de qualquer domínio, especifique:
```php
#[Requires(sameOrigin: false)]
public function handleList(): void
{
}
```
Acesso via Forward .[#toc-access-via-forward]
---------------------------------------------
Às vezes, é útil restringir o acesso a um apresentador para que ele esteja disponível apenas indiretamente, por exemplo, usando os métodos `forward()` ou `switch()` de outro apresentador. É assim que os apresentadores de erros são protegidos para evitar que sejam acionados a partir de um URL:
```php
#[Requires(forward: true)]
class ForwardedPresenter extends Nette\Application\UI\Presenter
{
}
```
Na prática, muitas vezes é necessário marcar determinadas exibições que só podem ser acessadas com base na lógica do apresentador. Novamente, para que elas não possam ser abertas diretamente:
```php
class ProductPresenter extends Nette\Application\UI\Presenter
{
public function actionDefault(int $id): void
{
$product = this->facade->getProduct($id);
if (!product) {
this->setView('notfound');
}
}
#[Requires(forward: true)]
public function renderNotFound(): void
{
}
}
```
Ações específicas .[#toc-specific-actions]
------------------------------------------
Você também pode restringir o acesso a determinados códigos, como a criação de um componente, apenas para ações específicas no apresentador:
```php
class EditDeletePresenter extends Nette\Application\UI\Presenter
{
#[Requires(actions: ['add', 'edit'])]
public function createComponentPostForm()
{
}
}
```
Para uma única ação, não há necessidade de escrever uma matriz: `#[Requires(actions: 'default')]`
Atributos personalizados .[#toc-custom-attributes]
--------------------------------------------------
Se você quiser usar o atributo `#[Requires]` repetidamente com as mesmas configurações, você pode criar seu próprio atributo que herdará o atributo `#[Requires]` e defini-lo de acordo com suas necessidades.
Por exemplo, `#[SingleAction]` permite o acesso somente por meio da ação `default`:
```php
#[Attribute]
class SingleAction extends Nette\Application\Attributes\Requires
{
public function __construct()
{
parent::__construct(actions: 'default');
}
}
#[SingleAction]
class SingleActionPresenter extends Nette\Application\UI\Presenter
{
}
```
Ou `#[RestMethods]` permitirá o acesso por meio de todos os métodos HTTP usados para a API REST:
```php
#[\Attribute]
class RestMethods extends Nette\Application\Attributes\Requires
{
public function __construct()
{
parent::__construct(methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
}
}
#[RestMethods]
class ApiPresenter extends Nette\Application\UI\Presenter
{
}
```
Conclusão .[#toc-conclusion]
----------------------------
O atributo `#[Requires]` oferece grande flexibilidade e controle sobre como as páginas da Web são acessadas. Usando regras simples, porém poderosas, você pode aumentar a segurança e o funcionamento adequado do seu aplicativo. Como você pode ver, o uso de atributos no Nette pode não apenas simplificar seu trabalho, mas também torná-lo seguro.
{{sitename: Best Practices}}