Autentificare
Nette oferă o modalitate de a programa autentificarea pe paginile noastre, dar nu ne impune nimic. Implementarea depinde în
totalitate de noi. Nette include interfața Nette\Security\Authenticator
, care necesită doar o singură metodă
authenticate
, care verifică utilizatorul în orice mod dorim.
Există multe posibilități prin care un utilizator poate fi verificat. Cea mai frecventă metodă de autentificare este prin parolă (utilizatorul furnizează numele său sau e-mailul și parola), dar există și alte metode. Poate cunoașteți butoanele de tip “Conectare cu Facebook” sau autentificarea prin Google/Twitter/GitHub pe unele site-uri. Cu Nette, putem avea orice metodă de autentificare sau le putem combina. Depinde doar de noi.
În mod normal, am scrie propriul nostru authenticator, dar pentru acest blog mic și simplu vom folosi authenticatorul
încorporat, care autentifică pe baza parolei și a numelui de utilizator stocate în fișierul de configurare. Este util în
scopuri de testare. Adăugăm deci următoarea secțiune security
în fișierul de configurare
config/common.neon
:
security:
users:
admin: secret # utilizator 'admin', parolă 'secret'
Nette va crea automat un serviciu în containerul DI.
Formular de autentificare
Acum avem autentificarea pregătită și trebuie să pregătim interfața utilizator pentru autentificare. Creăm deci un nou
presenter numit SignPresenter
, care:
- afișează formularul de autentificare (cu nume de utilizator și parolă)
- după trimiterea formularului, verifică utilizatorul
- oferă posibilitatea de deconectare
Începem cu formularul de autentificare. Știm deja cum funcționează formularele în presenteri. Creăm deci presenterul
SignPresenter
și scriem metoda createComponentSignInForm
. Ar trebui să arate cam așa:
<?php
namespace App\Presentation\Sign;
use Nette;
use Nette\Application\UI\Form;
final class SignPresenter extends Nette\Application\UI\Presenter
{
protected function createComponentSignInForm(): Form
{
$form = new Form;
$form->addText('username', 'Nume utilizator:')
->setRequired('Vă rugăm să completați numele de utilizator.');
$form->addPassword('password', 'Parolă:')
->setRequired('Vă rugăm să completați parola.');
$form->addSubmit('send', 'Autentificare');
$form->onSuccess[] = $this->signInFormSucceeded(...);
return $form;
}
}
Există câmpuri pentru nume de utilizator și parolă.
Șablon
Formularul va fi redat în șablonul in.latte
:
{block content}
<h1 n:block=title>Autentificare</h1>
{control signInForm}
Callback de autentificare
Apoi completăm callback-ul pentru autentificarea utilizatorului, care va fi apelat imediat după trimiterea cu succes a formularului.
Callback-ul preia pur și simplu numele de utilizator și parola pe care utilizatorul le-a completat și le transmite authenticatorului. După autentificare, redirecționăm către pagina principală.
private function signInFormSucceeded(Form $form, \stdClass $data): void
{
try {
$this->getUser()->login($data->username, $data->password);
$this->redirect('Home:');
} catch (Nette\Security\AuthenticationException $e) {
$form->addError('Nume de utilizator sau parolă incorectă.');
}
}
Metoda User::login() aruncă o excepție dacă numele de utilizator și parola nu corespund datelor din fișierul de configurare. După cum știm deja, acest lucru poate duce la o pagină roșie de eroare sau, în mod de producție, la un mesaj care informează despre o eroare de server. Nu dorim însă acest lucru. De aceea, prindem această excepție și transmitem un mesaj de eroare frumos și prietenos pentru utilizator în formular.
Odată ce apare o eroare în formular, pagina cu formularul se redesenează și deasupra formularului se afișează un mesaj frumos care informează utilizatorul că a introdus un nume de utilizator sau o parolă greșită.
Securizarea presenterilor
Vom securiza formularul pentru adăugarea și editarea postărilor. Acesta este definit în presenterul
EditPresenter
. Scopul este de a restricționa accesul la pagină pentru utilizatorii care nu sunt autentificați.
Creăm metoda startup()
, care se execută imediat la începutul ciclului de viață al presenterului.
Aceasta redirecționează utilizatorii neautentificați către formularul de autentificare.
public function startup(): void
{
parent::startup();
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Sign:in');
}
}
Ascunderea linkurilor
Utilizatorul neautorizat nu mai poate vedea pagina create sau edit, dar încă poate vedea linkurile către
acestea. Ar trebui să le ascundem și pe acestea. Un astfel de link se află în șablonul
app/Presentation/Home/default.latte
și ar trebui să fie vizibil doar pentru utilizatorii autentificați.
Îl putem ascunde folosind un n:atribut numit n:if
. Dacă această condiție este false
,
întregul tag <a>
, inclusiv conținutul, rămâne ascuns.
<a n:href="Edit:create" n:if="$user->isLoggedIn()">Creează postare</a>
ceea ce este o prescurtare a următoarei notații (a nu se confunda cu tag-if
):
{if $user->isLoggedIn()}<a n:href="Edit:create">Creează postare</a>{/if}
În același mod, ascundem și linkul din șablonul app/Presentation/Post/show.latte
.
Link către autentificare
Cum ajungem de fapt la pagina de autentificare? Nu există niciun link care să ducă la ea. Așa că îl vom adăuga în
șablonul @layout.latte
. Încercați să găsiți un loc potrivit – poate fi aproape oriunde.
...
<ul class="navig">
<li><a n:href="Home:">Articole</a></li>
{if $user->isLoggedIn()}
<li><a n:href="Sign:out">Deconectare</a></li>
{else}
<li><a n:href="Sign:in">Autentificare</a></li>
{/if}
</ul>
...
Dacă utilizatorul nu este autentificat, se afișează linkul “Autentificare”. În caz contrar, se afișează linkul
“Deconectare”. Vom adăuga și această acțiune în SignPresenter
.
Deoarece redirecționăm imediat utilizatorul după deconectare, nu este nevoie de niciun șablon. Deconectarea arată astfel:
public function actionOut(): void
{
$this->getUser()->logout();
$this->flashMessage('Deconectarea a avut succes.');
$this->redirect('Home:');
}
Se apelează doar metoda logout()
și apoi se afișează un mesaj frumos care confirmă deconectarea cu
succes.
Rezumat
Avem un link pentru autentificare și, de asemenea, pentru deconectarea utilizatorului. Pentru verificare, am folosit authenticatorul încorporat și avem datele de autentificare în fișierul de configurare, deoarece este o aplicație simplă de test. Am securizat, de asemenea, formularele de editare, astfel încât doar utilizatorii autentificați pot adăuga și edita postări.
Aici puteți citi mai multe despre autentificarea utilizatorilor și Autorizarea permisiunilor.