Autenticazione
Nette fornisce un modo per programmare l'autenticazione sulle nostre pagine, ma non ci obbliga a nulla. L'implementazione
dipende solo da noi. Nette contiene l'interfaccia Nette\Security\Authenticator
, che richiede solo un metodo
authenticate
, che verifica l'utente in qualsiasi modo desideriamo.
Ci sono molte opzioni su come un utente può essere autenticato. Il metodo di autenticazione più comune è tramite password (l'utente fornisce il proprio nome o e-mail e password), ma ci sono anche altri modi. Forse conoscete i pulsanti del tipo “Accedi con Facebook”, o l'accesso tramite Google/Twitter/GitHub su alcuni siti. Con Nette possiamo avere qualsiasi metodo di accesso, o possiamo anche combinarli. Dipende solo da noi.
Normalmente scriveremmo il nostro authenticator, ma per questo semplice piccolo blog useremo l'authenticator integrato, che
accede in base a password e nome utente memorizzati nel file di configurazione. È utile per scopi di test. Aggiungiamo quindi la
seguente sezione security al file di configurazione config/common.neon
:
security:
users:
admin: secret # utente 'admin', password 'secret'
Nette crea automaticamente un servizio nel container DI.
Form di accesso
Ora abbiamo l'autenticazione pronta e dobbiamo preparare l'interfaccia utente per l'accesso. Creiamo quindi un nuovo presenter chiamato SignPresenter, che:
- visualizzerà il form di accesso (con nome utente e password)
- dopo l'invio del form, verificherà l'utente
- fornirà la possibilità di disconnettersi
Iniziamo con il form di accesso. Sappiamo già come funzionano i form nei presenter. Creiamo quindi il presenter
SignPresenter
e scriviamo il metodo createComponentSignInForm
. Dovrebbe assomigliare a qualcosa del
genere:
<?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', 'Nome utente:')
->setRequired('Per favore, inserisci il tuo nome utente.');
$form->addPassword('password', 'Password:')
->setRequired('Per favore, inserisci la tua password.');
$form->addSubmit('send', 'Accedi');
$form->onSuccess[] = $this->signInFormSucceeded(...);
return $form;
}
}
Ci sono campi per nome utente e password.
Template
Il form verrà renderizzato nel template in.latte
:
{block content}
<h1 n:block=title>Accesso</h1>
{control signInForm}
Callback di accesso
Successivamente, aggiungiamo il callback per l'accesso dell'utente, che verrà chiamato subito dopo l'invio riuscito del form.
Il callback prende semplicemente il nome utente e la password che l'utente ha inserito e li passa all'authenticator. Dopo l'accesso, reindirizziamo alla pagina iniziale.
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('Nesprávné přihlašovací jméno nebo heslo.');
}
}
Il metodo User::login() lancerà un'eccezione se il nome utente e la password non corrispondono ai dati nel file di configurazione. Come già sappiamo, questo può portare a una pagina di errore rossa, o in modalità produzione a un messaggio che informa di un errore del server. Tuttavia, non vogliamo questo. Pertanto, catturiamo questa eccezione e passiamo un messaggio di errore carino e user-friendly al form.
Non appena si verifica un errore nel form, la pagina con il form viene ridisegnata e sopra il form viene visualizzato un messaggio carino che informa l'utente che ha inserito un nome utente o una password errati.
Protezione dei presenter
Proteggiamo il form per l'aggiunta e la modifica dei post. Questo è definito nel presenter EditPresenter
.
L'obiettivo è impedire l'accesso alla pagina agli utenti che non sono loggati.
Creiamo il metodo startup()
, che viene eseguito immediatamente all'inizio del ciclo di vita del presenter. Questo
reindirizzerà gli utenti non loggati al form di accesso.
public function startup(): void
{
parent::startup();
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Sign:in');
}
}
Nascondere i link
Un utente non autorizzato non può più vedere la pagina create né edit, ma può ancora vedere i link ad esse.
Dovremmo nascondere anche questi. Uno di questi link si trova nel template app/Presentation/Home/default.latte
e
dovrebbe essere visibile solo agli utenti loggati.
Possiamo nasconderlo utilizzando un n:attributo chiamato n:if
. Se questa condizione è false
,
l'intero tag <a>
, incluso il contenuto, rimarrà nascosto.
<a n:href="Edit:create" n:if="$user->isLoggedIn()">Crea post</a>
che è l'abbreviazione della seguente notazione (da non confondere con tag-if
):
{if $user->isLoggedIn()}<a n:href="Edit:create">Crea post</a>{/if}
Allo stesso modo, nascondiamo anche il link nel template app/Presentation/Post/show.latte
.
Link di accesso
Come arriviamo effettivamente alla pagina di accesso? Non c'è nessun link che porti ad essa. Quindi aggiungiamolo al template
@layout.latte
. Provate a trovare un posto adatto – può essere quasi ovunque.
...
<ul class="navig">
<li><a n:href="Home:">Articoli</a></li>
{if $user->isLoggedIn()}
<li><a n:href="Sign:out">Esci</a></li>
{else}
<li><a n:href="Sign:in">Accedi</a></li>
{/if}
</ul>
...
Se l'utente non è loggato, verrà visualizzato il link “Accedi”. Altrimenti, verrà visualizzato il link “Esci”.
Aggiungiamo anche questa azione a SignPresenter
.
Poiché reindirizziamo immediatamente l'utente dopo la disconnessione, non è necessario alcun template. La disconnessione assomiglia a questo:
public function actionOut(): void
{
$this->getUser()->logout();
$this->flashMessage('Odhlášení bylo úspěšné.');
$this->redirect('Home:');
}
Viene semplicemente chiamato il metodo logout()
e successivamente viene visualizzato un messaggio carino che
conferma la disconnessione riuscita.
Riepilogo
Abbiamo un link per l'accesso e anche per la disconnessione dell'utente. Per l'autenticazione abbiamo utilizzato l'authenticator integrato e i dati di accesso li abbiamo nel file di configurazione, poiché si tratta di una semplice applicazione di test. Abbiamo anche protetto i form di modifica, quindi solo gli utenti loggati possono aggiungere e modificare i post.
Qui potete leggere di più sul login degli utenti e sulla Verifica delle autorizzazioni.