Laravel umožňuje vytvořit přihlášení do aplikace velmi jednoduše. Prakticky je již vše připraveno a není potřeba instalovat žádný další balíček. V tomto díle se podíváme na základní přihlašování přes Laravel, jeho konfiguraci a také si řekneme něco o jiných alternativách.

Inicializace

Pro vytvoření autentizačních rout, controllerů a pohledů je potřeba spustit příkaz:

php artisan make:auth

Je pravděpodobné, že vám vyskočí následující upozornění:

The [layouts/app.blade.php] view already exists. Do you want to replace it? (yes/no) [no]:

Zadejte "no" protože nechceme nic přepisovat, jelikož jsme si svůj layout již vytvořili podle našich potřeb. Následně by se měla zobrazit pouze potvrzující hláška "Authentication scaffolding generated successfully."

Migrace jste již pravděpodobně spustili v některém z dřívějších dílů, nicméně pro jistotu můžete znovu zadat příkaz pro spuštění migrací:

php artisan migrate

Úpravy a konfigurace

Po spuštění příkazu make:auth  se nám vytvořilo několik pohledů, jeden controller a upravili se nám routy. Defaultně Laravel nabízí kromě registrace a přihlašování také možnost nechat si zaslat email pro vygenerování nového hesla v případě jeho zapomenutí. Tuto funkcionalitu nebudeme v našem blogu využívat, jelikož přihlášení bude sloužit výhradně pouze administrátorovi. Je jen na vás jestli dané soubory smažete nebo si je necháte a třeba si je do projektu doimplementujete. Celá registrace a přihlášení je nyní k dispozici a můžete si ji klidně vyzkoušet na routách /register  nebo /login . Jen upozorňuji, jak dále zjistíte, cesta /logout  pro odhlášení vyžaduje HTTP požadavek typu POST, takže pokud se přihlásíte, je potřeba přes POST se zase odhlásit. V další části tohoto článku si blog upravíme, abychom se mohli pohodlně odhlásit.

Controllery

Laravel již po nainstalování nabízí několik controllerů co se týče autentizace. Tyto controllery najdete v adresáři app/Http/Controllers/Auth . Nás zajímají hlavně třídy LoginController  a RegisterController . Když se podíváte na jejich kód tak zjistíte, že jsou poměrně primitivní a neobsahují žádnou složitější logiku. Obě třídy však používají traity Illuminate\Foundation\Auth\AuthenticatesUsers  a  Illuminate\Foundation\Auth\RegistersUsers . Tyto traity obsahují další metody, které autentizace využívá a doporučuji si je projít. Jedinou změnu, kterou v obou třídách provedeme, je úprava proměnné třídy $redirectTo :

protected $redirectTo = '/';

Díky tomu nás to po přihlášení nebo registraci přesměruje na domovskou stránku s výpisem článku.

Kromě jiného se nám vytvořila třída app/Http/Controllers/HomeController , která defaultně slouží jako úvodní stránka po přihlášení/registraci. Protože nám pro domovskou stránku slouží controller PostController , můžeme tento nově vygenerovaný soubor klidně smazat.

Routy

Artisan nám přidal také cesty v routes/web.php :

Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');

Opět můžeme smazat cestu pro /home , jelikož ji nebudeme využívat. Co nás ale hlavně zajímá je první řádek, který obaluje autentizační metody. Odkazuje do třídy Illuminate/Routing/Router  a přesněji obsahuje tyto cesty:

// Authentication Routes...
$this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController@login');
$this->post('logout', 'Auth\LoginController@logout')->name('logout');

// Registration Routes...
$this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
$this->post('register', 'Auth\RegisterController@register');

// Password Reset Routes...
$this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController@reset');

Jak jsem již dříve psal, všimněte si, že cesta /logout  pro odhlášení je typu POST. To je především kvůli bezpečnosti proti útoku typu CSRF.

Pohledy

V resources/views/auth  se nám vytvořilo několik blade šablon, které zobrazují přihlašovací a registrační formulář, případně v adresáři /passwords  najdeme šablony pro resetování hesla (opět můžeme smazat pokud je nebudete používat). Pro jednoduchost tutoriálu necháme vše tak jak je, jen v login.blade.php  odebereme odkaz pro resetování hesla. Případně je možné si formuláře počeštit.

Artisan i zde vytvořil novou šablonu resources/views/home.blade.php  pro úvodní stránku. Tuto šablonu můžeme klidně smazat.

Poslední úpravu, kterou provedeme, bude úprava navigace. Protože přihlašovat se bude pouze admin, tak není potřeba nikde dávat možnost přesměrovat na přihlašovací stránku a pouze administrátor bude vědět, že se do administrace přihlásí přes cestu /login . Podobně to tak je například i ve Wordpressu. Naopak pokud je admin přihlášen, tak by bylo příjemné mít v navigaci možnost se odhlásit. Toho dosáhneme úpravou dropdownu v resources/views/includes/navigation.blade.php :

@if(Auth::check())
<li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" data-toggle="dropdown" id="login" href="#" role="button" aria-haspopup="true" aria-expanded="false"> Login </a>
    <div class="dropdown-menu" aria-labelledby="login">
    <form id="frm-logout" action="{{ route('logout') }}" method="POST">
        <button class="dropdown-item" type="submit" style="cursor: pointer">Odhlášení</button>
        {{ csrf_field() }}
    </form>
    </div>
</li>
@endif

Všimněte si podmínky Auth::check() . Ta nám přes fasádu zkontroluje, jestli je uživatel přihlášený a pokud ano, zobrazí se dropdown. Přihlášení se dá kontrolovat v šablonách i v controllerech, nejvíce užitečné je ale je kontrolovat již v middleware, takže se kontrola přihlášení provede ještě dříve, než požadavek dojde ke controlleru.

Alternativy

Laravel nabízí hned od začátku celý proces registrace a přihlášení a v podstatě plní zcela svůj účel. Nicméně pokud bychom chtěli vytvořit ACL s rozdělením na práva a role, pak je potřeba si to udělat po svém, nebo využít nějaký externí balíček.

Jako první bych zmínil balíček Laravel-permission od společnosti Spatie. Osobně s tímto balíčkem nemám žádné zkušenosti, nicméně často narážím na články, které tento balíček využívají a dále rozšiřují. Určitě doporučuji se na něj podívat a vyzkoušet si, jestli vám vyhovuje a splňuje vaše požadavky.

Jinou možností je Sentinel od firmy Cartalyst. S tímto balíčkem mám několikaleté zkušenosti a upřímně můžu říct, že kdybych si mohl znovu vybrat, zvolil bych si jiný balíček. Balíček jako takový splňuje svůj účel, velmi dobře se s ním pracuje a jako takový není nijak složitý. Problém je v tom, že se jeho vývoj velmi zpomalil, ne-li úplně zastavil (viz Github kde poslední changelog je z roku 2015). Díky tomu občas narážím dle mého názoru na bugy, kde například není možné volat autentizaci v konstruktoru třídy, nelze ho využít v service providerech a musí se nastavovat v middlewarech apod. Sentinel nabízí dvě možnosti, nativní pro autentizaci bez Laravelu a druhou přes fasády frameworku. Když jsem ale chtěl tyto možnosti zkombinovat tak jedna strana neviděla přihlášeného uživatele a naopak. Stejně tak jsem mnoho věcí musel hledat na netu, protože dokumentace řekněme neobsahuje vše. To jsou ale mé osobní závěry, balíček jako takový funguje správně, jen je občas potřeba počítat s bugy.

Alternativ pro autentizaci, především pak společně s ACL, je velmi mnoho. Stačí na Google zadat "Laravel ACL" a uvidíte, kolik výsledků vám toho najde. Doporučuji ale vždy mrknout na github (případně někam jinam) projektu a zjistit si aktuálnost projektu. Často narazíte na to, že byl plugin vytvořen např. pro verzi Laravel 5.4 a od té doby se nic dalšího nezměnilo. Určitě je lepší mít produkt, na kterým se stále pracuje a upravují se chyby, než mít balíček, kde se chybami musíte (a často zcela zbytečně) poprat sami.

Není vám něco jasné, nefunguje nebo mám někde chybu? Napište do komentářů!

Zdrojové kódy pro tento díl naleznete na GitHubu

Užitečné odkazy: