Autentificare
Nette vă oferă îndrumări cu privire la modul în care să programați autentificarea pe pagina dvs., dar nu vă obligă să
faceți acest lucru într-un anumit mod. Implementarea depinde de dumneavoastră. Nette are o interfață
Nette\Security\Authenticator
care vă obligă să implementați doar o singură metodă numită
authenticate
, care găsește utilizatorul în orice mod doriți.
Există mai multe moduri în care un utilizator se poate autentifica. Cel mai comun mod este Autentificarea pe bază de parolă (utilizatorul își furnizează numele sau adresa de e-mail și o parolă), dar există și alte mijloace. Probabil că sunteți familiarizat cu butoanele “Autentificare cu Facebook” de pe multe site-uri web sau autentificarea prin Google/Twitter/GitHub sau orice alt site. Cu Nette, puteți avea orice metodă de autentificare doriți, sau le puteți combina. Depinde de dumneavoastră.
În mod normal, ar trebui să vă scrieți propriul autentificator, dar pentru acest mic blog simplu vom folosi
autentificatorul încorporat, care se autentifică pe baza unei parole și a unui nume de utilizator stocate într-un fișier de
configurare. Este bun pentru scopuri de testare. Așadar, vom adăuga 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 înregistrare
Acum avem gata partea de autentificare din backend și trebuie să furnizăm o interfață de utilizator, prin care utilizatorul se va autentifica. Haideți să creăm un nou prezentator numit SignPresenter, care va
- va afișa un formular de autentificare (care va cere numele de utilizator și parola)
- va autentifica utilizatorul atunci când formularul este trimis
- să ofere o acțiune de deconectare
Să începem cu formularul de autentificare. Știți deja cum funcționează formularele într-un prezentator. Creați
SignPresenter
și metoda createComponentSignInForm
. Ar trebui să arate astfel:
<?php
namespace App\UI\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', 'Username:')
->setRequired('Please enter your username.');
$form->addPassword('password', 'Password:')
->setRequired('Please enter your password.');
$form->addSubmit('send', 'Sign in');
$form->onSuccess[] = $this->signInFormSucceeded(...);
return $form;
}
}
Există o intrare pentru numele de utilizator și parola.
Șablon
Formularul va fi redat în șablon in.latte
{block content}
<h1 n:block=title>Sign in</h1>
{control signInForm}
Manipulator de autentificare
Adăugăm, de asemenea, un manager de formular pentru autentificarea utilizatorului, care este invocat imediat după ce formularul este trimis.
Manipulatorul va lua doar numele de utilizator și parola introduse de utilizator și le va transmite către autentificatorul definit anterior. După ce utilizatorul s-a logat, îl vom redirecționa către pagina de start.
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('Incorrect username or password.');
}
}
Metoda User::login() ar trebui să arunce o excepție atunci când numele de utilizator sau parola nu se potrivește cu cele pe care le-am definit anterior. După cum știm deja, acest lucru ar avea ca rezultat un ecran roșu Tracy sau, în modul de producție, un mesaj care să informeze despre o eroare internă a serverului. Nu ne-ar plăcea acest lucru. De aceea, capturăm excepția și adăugăm un mesaj de eroare frumos și prietenos în formular.
Atunci când apare eroarea în formular, pagina cu formularul va fi redată din nou, iar deasupra formularului va apărea un mesaj frumos, informând utilizatorul că a introdus un nume de utilizator sau o parolă greșită.
Securitatea prezentatorilor
Vom securiza un formular pentru adăugarea și editarea mesajelor. Acesta este definit în prezentator
EditPresenter
. Scopul este de a împiedica utilizatorii care nu sunt conectați să acceseze pagina.
Creăm o metodă startup()
care este lansată imediat la începutul ciclului de viață al prezentatorului.
Aceasta redirecționează utilizatorii care nu sunt autentificați către formularul de autentificare.
public function startup(): void
{
parent::startup();
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Sign:in');
}
}
Ascundeți linkurile
Un utilizator neautentificat nu mai poate vedea nici pagina create, nici pagina edit, dar poate vedea în
continuare legăturile care indică spre ele. Haideți să le ascundem și pe acestea. Un astfel de link se află în
app/UI/Home/default.latte
, și ar trebui să fie vizibil numai dacă utilizatorul este autentificat.
Îl putem ascunde folosind n:atribut numit n:if
. Dacă afirmația din interiorul acestuia este
false
, întregul <a>
tag și conținutul său nu vor fi afișate:
<a n:href="Edit:create" n:if="$user->isLoggedIn()">Create post</a>
aceasta este o prescurtare pentru (nu o confundați cu tag-if
):
{if $user->isLoggedIn()}<a n:href="Edit:create">Create post</a>{/if}
Ar trebui să ascundeți linkul de editare aflat în app/UI/Post/show.latte
într-un mod similar.
Legătura formularului de autentificare
Hei, dar cum ajungem la pagina de autentificare? Nu există nici un link care să arate spre ea. Să adăugăm unul în
fișierul șablon @layout.latte
. Încercați să găsiți un loc frumos, poate fi oriunde vă place cel
mai mult.
...
<ul class="navig">
<li><a n:href="Home:">Home</a></li>
{if $user->isLoggedIn()}
<li><a n:href="Sign:out">Sign out</a></li>
{else}
<li><a n:href="Sign:in">Sign in</a></li>
{/if}
</ul>
...
Dacă utilizatorul nu este încă logat, vom afișa link-ul “Sign in”. În caz contrar, vom afișa linkul “Sign out”. Adăugăm această acțiune în SignPresenter.
Acțiunea de deconectare arată astfel și, deoarece redirecționăm utilizatorul imediat, nu este nevoie de un șablon de vizualizare.
public function actionOut(): void
{
$this->getUser()->logout();
$this->flashMessage('You have been signed out.');
$this->redirect('Home:');
}
Pur și simplu se apelează metoda logout()
și apoi se afișează un mesaj frumos pentru utilizator.
Rezumat
Avem un link pentru a ne conecta și pentru a deconecta utilizatorul. Am folosit autentificatorul încorporat pentru autentificare, iar detaliile de conectare se află în fișierul de configurare, deoarece aceasta este o simplă aplicație de testare. De asemenea, am securizat formularele de editare astfel încât numai utilizatorii autentificați să poată adăuga și edita postări.
Aici puteți citi mai multe despre autentificarea și autorizarea utilizatorilor.