Autenticazione su più tabelle con MultiAuth

0
157

Il sistema di autenticazione è uno dei componenti più interessanti (e potenti) di Laravel. Permette di gestire tutta la procedura di accesso e non solo, dato che presenta anche delle routine di recupero delle credenziali già pronte. Tanto da arrivare al livello, a volte, di dover scrivere solo due o tre righe di codice.

Anche un sistema del genere, però, ha i suoi limiti: qualche giorno fa, su un forum, un ragazzo chiedeva informazioni su come usare più tabelle per memorizzare i dati degli utenti. Una tabella per gli amministratori, una tabella per gli utenti, e così via.

Oggi non mi metterò a pontificare su quale pratica è giusta e quale è sbagliata: sappiamo bene che le necessità cambiano di progetto in progetto.

Quello che faremo in questo articolo sarà scoprire, insieme, il package ollieread/multiauth.

Come spiega anche l’autore del package, non si tratta di un rimpiazzo al 100%: è più un qualcosa che si frappone nel mezzo, un layer, o per essere più precisi una sorta di Factory Class.

Permette quindi di usare diverse accoppiate model/tabella. Come se non bastasse, inoltre, permette di associare ad ognuna di queste combinazioni un driver diverso. Quindi, per assurdo, se avessimo gli amministratori su SQL Server e gli utenti su MySQL… beh, nessun problema.

Vediamo innanzitutto come aggiungerlo al nostro progetto.

Installazione

Installare multiauth è davvero semplice: basta procedere con Composer.

Aggiungiamo la seguente dipendenza al nostro progetto:

“require”: {
“ollieread/multiauth”: “dev-master”
}

Al momento in cui scrivo la versione stable è la 3.2.3. Aggiorniamo il nostro progetto tramite _composer update, quindi provvediamo a sostituire l’AuthServiceProvider con

“OlliereadMultiauthMultiauthServiceProvider”

nel file app/config/app.php, tra gli elementi dell’array providers.

Dopodiché passiamo al file app/config/auth.php. Questa è la configurazione di default che dovresti già trovare:

return array(

‘driver’ => ‘eloquent’,

‘model’ => ‘User’,

‘table’ => ‘users’,

‘reminder’ => array(

‘email’ => ‘emails.auth.reminder’,

‘table’ => ‘password_reminders’,

‘expire’ => 60,

),

);

Ovviamente non ci serve più: deve essere rimpiazzata con quella di cui abbiamo bisogno. Supponiamo quindi di avere la necessità di due tipologie diverse di utenti:
* Utenti (User);
* Amministratori (Administrator);

Ecco quale sarà il contenuto del file di configurazione risultante:

return array(

‘multi’ => array(
‘administrator’ => array(
‘driver’ => ‘eloquent’,
‘model’ => ‘Account’
),
‘user’ => array(
‘driver’ => ‘eloquent’,
‘model’ => ‘Administrator’
)
),

‘reminder’ => array(

‘email’ => ‘emails.auth.reminder’,

‘table’ => ‘password_reminders’,

‘expire’ => 60,

),

);

Inutile dire che puoi aggiungere tutte le tipologie di utenti di cui hai bisogno.

Procedura di Autenticazione

L’uso del package è semplicissimo, considerando che consiste fondamentalmente nell’aggiunta di un’istruzione in più in fase di chiamata di qualsiasi metodo.

Ad esempio, se fino ad ora nel nostro codice abbiamo un’istruzione quale

Auth::attempt(array(
‘email’ => $attributes[‘email’],
‘password’ => $attributes[‘password’],
));

adesso non dobbiamo fare altro che aggiungere, subito dopo “Auth::“, il nome dell’entità di cui abbiamo bisogno.

Vediamo i due esempi riprendendo in considerazione le due entità viste prima.

Auth::user()->attempt(array(
‘email’ => $attributes[‘email’],
‘password’ => $attributes[‘password’],
));

Auth::administrator()->attempt(array(
‘email’ => $attributes[‘email’],
‘password’ => $attributes[‘password’],
));

Anche le altre istruzioni rimangono identiche, seguendo la stessa filosofia:

Auth::user()->check();
Auth::administrator()->check();

L’unica eccezione riguarda il metodo da usare per ottenere i dati dell’utente loggato attualmente: per evitare, infatti, la ripetizione

Auth::user()->user();

è stato introdotto il metodo “get()“, più generico, comodo e meno propenso all’ambiguità.

Auth::user()->get();
Auth::administrator()->get();

Davvero molto interessante, inoltre, è il metodo impersonate(), che consente ad un utente di un’altra categoria di “simulare” l’accesso con un’altra tipologia di utente.

Auth::administrator()->impersonate(‘user’, 1, true);

In questo caso, l’amministratore corrente sta “impersonando” l’utente dall’id uguale ad 1. Il terzo parametro è un flag “remember me” per ricordare l’accesso. Di default è impostato su false.

Password Reminder

Non solo login: il package di autenticazione di Laravel, infatti, include anche tutta una serie di utility e metodi dedicati al recovery delle credenziali utente. Chiaramente, multiauth non poteva rimanere a piedi sotto questo punto di vista.

Configurazione

Nel caso decidessimo di lavorare anche con questo insieme di funzionalità, la prima cosa da fare è sostituire il _ReminderServiceProvider _con il seguente:

OlliereadMultiauthRemindersReminderServiceProvider

Provvediamo quindi ad installare la tabella dei reminder tramite Artisan:

php artisan multiauth:reminders-table

… e siamo pronti!

**Nota: **al momento in cui scrivo non esiste l’equivalente del comando reminder-controller. Lo sviluppatore ha accennato, tuttavia, di volerlo implementare in un futuro prossimo.

Utilizzo

L’utilizzo del package in tal senso è praticamente lo stesso, seguendo la stessa procedura vista prima per l’accesso ed il check.

L’invio del reminder va implementato con il metodo “remind()”, appunto:

Password::administrator()->remind(Input::only(‘email’), function($message) {
$message->subject(‘Recupero Credenziali’);
});

ed il reset con il metodo omonimo.

Password::administrator()->reset($credentials, function($user, $password) {
$user->password = Hash::make($password);
$user->save();
});

Va ricordato comunque che l’url generato in questo caso dovrà essere diverso: l’istruzione da inserire nella view del reminder sarà la seguente.

{{ URL::to(‘password/reset’, array($type, $token)) }}

Tale istruzione genererà un link simile al seguente:

http://myhost.dev/password/reset/administrator/27eb8fe5fe666b3b8d0521156bbf53266dbca572

Il penultimo segmento indica il tipo di utente, l’ultimo il token da usare.

Tale URL corrisponderà ovviamente ad una route specifica di questo genere:

Route::any(‘/password/reset/{type}/{token}’, ‘Controller@method’);

Note sui Filtri

Come giustamente lo sviluppatore ricorda, nel file dei filtri _filters.php _ci sono dei filtri che fanno uso del metodo Auth::guest(). Ricorda di modificarli adeguatamente e, se ne avessi bisogno, trovi un gist all’indirizzo https://gist.github.com/ollieread/8303638.

Conclusioni

Non nego di aver usato un paio di volte questo package che mi ha semplificato enormemente la vita. Potrebbe servire anche a te, magari, e ho pensato di scriverci su un articolo. Tu che ne pensi, potrebbe esserti utile?

Per qualsiasi feedback non esitare a commentare!