Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
2,768 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
Как да използвате `#[Requires]` Атрибут | ||
*************************************** | ||
|
||
.[perex] | ||
Когато пишете уеб приложение, често се сблъсквате с необходимостта да ограничите достъпа до определени части на приложението. Може би искате някои заявки да могат да изпращат данни само чрез формуляр (като по този начин се използва методът POST) или да са достъпни само за AJAX повиквания. В Nette Framework 3.2 е въведен нов инструмент, който ви позволява да задавате такива ограничения по елегантен и ясен начин: инструментът `#[Requires]` атрибут. | ||
|
||
Атрибутът е специален маркер в PHP, който се добавя преди дефиницията на клас или метод. Тъй като по същество това е клас, трябва да включите клаузата use: | ||
|
||
```php | ||
use Nette\Application\Attributes\Requires; | ||
``` | ||
|
||
. `#[Requires]` Атрибутът може да се използва за класовете на презентаторите и следните методи: | ||
|
||
- `action<Action>()` | ||
- `render<View>()` | ||
- `handle<Signal>()` | ||
- `createComponent<Name>()` | ||
|
||
Последните два метода също се отнасят за всички компоненти. | ||
|
||
Ако условията не са изпълнени, се задейства HTTP 40x грешка. | ||
|
||
|
||
HTTP методи .[#toc-http-methods] | ||
-------------------------------- | ||
|
||
Можете да зададете кои HTTP методи (като GET, POST и т.н.) са разрешени за достъп. Например, ако искате да разрешите достъп само чрез изпращане на формуляр, задайте: | ||
|
||
```php | ||
#[Requires(methods: 'POST')] | ||
class FormPresenter extends Nette\Application\UI\Presenter | ||
{ | ||
} | ||
``` | ||
|
||
|
||
Извиквания AJAX .[#toc-ajax-calls] | ||
---------------------------------- | ||
|
||
Ако искате даден презентатор или метод да бъде достъпен само за AJAX заявки, използвайте: | ||
|
||
```php | ||
#[Requires(ajax: true)] | ||
class AjaxPresenter extends Nette\Application\UI\Presenter | ||
{ | ||
} | ||
``` | ||
|
||
|
||
Същият произход .[#toc-same-origin] | ||
----------------------------------- | ||
|
||
За да повишите сигурността, можете да изисквате заявката да бъде направена от същия домейн: | ||
|
||
```php | ||
#[Requires(sameOrigin: true)] | ||
class SecurePresenter extends Nette\Application\UI\Presenter | ||
{ | ||
} | ||
``` | ||
|
||
За `handle<Signal>()` методи това се изисква автоматично. И обратното, ако искате да разрешите достъп от всеки домейн, посочете: | ||
|
||
```php | ||
#[Requires(sameOrigin: false)] | ||
public function handleList(): void | ||
{ | ||
} | ||
``` | ||
|
||
|
||
Достъп чрез Forward .[#toc-access-via-forward] | ||
---------------------------------------------- | ||
|
||
Понякога искате да ограничите достъпа до даден презентатор, така че той да е достъпен само косвено, например чрез метода `forward()` от друг презентатор. По този начин се защитават презентаторите на грешки, така че да не могат да бъдат извикани от URL адрес: | ||
|
||
```php | ||
#[Requires(forward: true)] | ||
class ForwardedPresenter extends Nette\Application\UI\Presenter | ||
{ | ||
} | ||
``` | ||
|
||
Можете също така да ограничите определени изгледи, до които може да се получи достъп въз основа на логиката в презентатора: | ||
|
||
```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 | ||
{ | ||
} | ||
} | ||
``` | ||
|
||
|
||
Специфични действия .[#toc-specific-actions] | ||
-------------------------------------------- | ||
|
||
Можете също така да ограничите достъпа до определен код, като например създаване на компонент, само за определени действия в презентатора: | ||
|
||
```php | ||
class EditDeletePresenter extends Nette\Application\UI\Presenter | ||
{ | ||
#[Requires(actions: ['add', 'edit'])] | ||
public function createComponentPostForm() | ||
{ | ||
} | ||
} | ||
``` | ||
|
||
За едно действие не е необходимо да се пише масив: `#[Requires(actions: 'default')]` | ||
|
||
|
||
Потребителски атрибути .[#toc-custom-attributes] | ||
------------------------------------------------ | ||
|
||
Ако искате да използвате `#[Requires]` атрибут с едни и същи настройки, можете да създадете свой собствен атрибут, който ще наследи `#[Requires]` и да го настроите според нуждите си. | ||
|
||
Например, `#[SingleAction]` позволява достъп само чрез действието `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 | ||
{ | ||
} | ||
``` | ||
|
||
Или `#[AllowAllMethods]` позволява достъп чрез всички HTTP методи, което стандартните презентатори [не позволяват от съображения за сигурност |application:presenters#toc-http-method-control]. | ||
|
||
```php | ||
#[\Attribute] | ||
class AllowAllMethods extends Nette\Application\Attributes\Requires | ||
{ | ||
public function __construct() | ||
{ | ||
parent::__construct(methods: ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH']); | ||
} | ||
} | ||
|
||
#[AllowAllMethods] | ||
class OpenPresenter extends Nette\Application\UI\Presenter | ||
{ | ||
} | ||
``` | ||
|
||
|
||
Заключение .[#toc-conclusion] | ||
----------------------------- | ||
|
||
На `#[Requires]` ви дава голяма гъвкавост и контрол върху начина, по който се осъществява достъпът до вашите уеб страници. С помощта на прости, но мощни правила можете да повишите сигурността и правилното функциониране на вашето приложение. Както виждате, използването на атрибути в Nette може не само да опрости работата ви, но и да я осигури. | ||
|
||
{{sitename: Best Practices}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
Jak používat atribut `#[Requires]` | ||
********************************** | ||
|
||
.[perex] | ||
Když píšete webovou aplikaci, často se setkáte s potřebou omezit přístup k určitým částem vaší aplikace. Možná chcete, aby některé požadavky mohly odesílat data pouze pomocí formuláře (tedy metodou POST), nebo aby byly přístupné pouze pro AJAXové volání. V Nette Frameworku 3.2 se objevil nový nástroj, který vám umožní taková omezení nastavit velmi elegantně a přehledně: atribut `#[Requires]`. | ||
|
||
Atribut je speciální značka v PHP, kterou přidáte před definici třídy nebo metody. Protože jde vlastně o třídu, je nutné uvést klauzuli use: | ||
|
||
```php | ||
use Nette\Application\Attributes\Requires; | ||
``` | ||
|
||
Atribut `#[Requires]` můžete použít na třídy presenterů i na tyto metody: | ||
|
||
- `action<Action>()` | ||
- `render<View>()` | ||
- `handle<Signal>()` | ||
- `createComponent<Name>()` | ||
|
||
Poslední dvě metody se týkají také všech komponent. | ||
|
||
Pokud nejsou splněny podmínky, dojde k vyvolání HTTP chyby 40x. | ||
|
||
|
||
Metody HTTP | ||
----------- | ||
|
||
Můžete specifikovat, které HTTP metody (jako GET, POST atd.) jsou pro přístup povolené. Například, pokud chcete povolit přístup pouze odesíláním formuláře, nastavíte: | ||
|
||
```php | ||
#[Requires(methods: 'POST')] | ||
class FormPresenter extends Nette\Application\UI\Presenter | ||
{ | ||
} | ||
``` | ||
|
||
|
||
AJAXové volání | ||
-------------- | ||
|
||
Pokud chcete, aby byl presenter nebo metoda dostupná pouze pro AJAXové požadavky, použijte: | ||
|
||
```php | ||
#[Requires(ajax: true)] | ||
class AjaxPresenter extends Nette\Application\UI\Presenter | ||
{ | ||
} | ||
``` | ||
|
||
|
||
Stejný původ | ||
------------ | ||
|
||
Pro zvýšení bezpečnosti můžete vyžadovat, aby byl požadavek učiněn ze stejné domény: | ||
|
||
```php | ||
#[Requires(sameOrigin: true)] | ||
class SecurePresenter extends Nette\Application\UI\Presenter | ||
{ | ||
} | ||
``` | ||
|
||
U metod `handle<Signal>()` je tohle vyžadováno automaticky. Pokud naopak chcete povolit přístup z jakékoliv domény, uveďte: | ||
|
||
```php | ||
#[Requires(sameOrigin: false)] | ||
public function handleList(): void | ||
{ | ||
} | ||
``` | ||
|
||
|
||
Přístup přes forward | ||
-------------------- | ||
|
||
Někdy chcete omezit přístup k presenteru tak, aby byl dostupný pouze nepřímo, například použitím metody `forward()` z jiného presenteru. Takto se třeba chrání error-presentery, aby je nebylo možné vyvolat z URL: | ||
|
||
```php | ||
#[Requires(forward: true)] | ||
class ForwardedPresenter extends Nette\Application\UI\Presenter | ||
{ | ||
} | ||
``` | ||
|
||
Také můžete omezit určité views, ke kterým se lze dostat až na základě logiky v presenteru: | ||
|
||
```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 | ||
{ | ||
} | ||
} | ||
``` | ||
|
||
|
||
Konkrétní akce | ||
-------------- | ||
|
||
Můžete také omezit, že určitý kód, třeba vytvoření komponenty, bude dostupné pouze pro specifické akce v presenteru: | ||
|
||
```php | ||
class EditDeletePresenter extends Nette\Application\UI\Presenter | ||
{ | ||
#[Requires(actions: ['add', 'edit'])] | ||
public function createComponentPostForm() | ||
{ | ||
} | ||
} | ||
``` | ||
|
||
V případě jedné akce není potřeba zapisovat pole: `#[Requires(actions: 'default')]` | ||
|
||
|
||
Vlastní atributy | ||
---------------- | ||
|
||
Pokud chcete použít atribut `#[Requires]` opakovaně s týmž nastavením, můžete si vytvořit vlastní atribut, který bude dědit `#[Requires]` a nastaví ho podle potřeb. | ||
|
||
Například `#[SingleAction]` umožní přístup pouze přes akci `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 | ||
{ | ||
} | ||
``` | ||
|
||
Nebo `#[AllowAllMethods]` umožní přístup přes všechny HTTP metody, což standardně presentery z bezpečnostních důvodů [nedovolují |application:presenters#toc-kontrola-http-metody]. | ||
|
||
```php | ||
#[\Attribute] | ||
class AllowAllMethods extends Nette\Application\Attributes\Requires | ||
{ | ||
public function __construct() | ||
{ | ||
parent::__construct(methods: ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH']); | ||
} | ||
} | ||
|
||
#[AllowAllMethods] | ||
class OpenPresenter extends Nette\Application\UI\Presenter | ||
{ | ||
} | ||
``` | ||
|
||
|
||
Závěr | ||
----- | ||
|
||
Atribut `#[Requires]` vám dává velkou flexibilitu a kontrolu nad tím, jak jsou vaše webové stránky přístupné. Pomocí jednoduchých, ale mocných pravidel můžete zvýšit bezpečnost a správné fungování vaší aplikace. Jak vidíte, použití atributů v Nette může vaši práci nejen usnadnit, ale i zabezpečit. | ||
|
||
{{sitename: Best Practices}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.