Laravel 5.4: Trabalhando com autenticações independentes sem packages adicionais

Renan Coelho
Jun 18, 2017 · 5 min read

Neste artigo irei trazer uma característica interessante do Laravel, que é a forma fácil de trabalhar com sistema de autenticação independente.

Para exemplificar, iremos criar 3 tipos de autenticação: Usuário, Administrador e Anunciante.


Preparando nossa aplicação

Iremos preparar nossa aplicação editando as configurações de autenticação em config\auth.php:

Na seção defaults mudamos nosso guard padrão web para user:

'defaults' => [
'guard' => 'user',
'passwords' => 'users',
],

Na seção guards precisamos informar ao Laravel nossos três tipos de autenticação: user (Usuário), admin (Administrador), ad (Anunciante)

'guards' => [
'user' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'ad' => [
'driver' => 'session',
'provider' => 'ads',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],

Na seção providers precisamos informar ao Laravel nossos três providers de autenticação:

'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
'ads' => [
'driver' => 'eloquent',
'model' => App\Ad::class,
],
],

Na seção passwords configuramos nossas tabelas para que o Laravel guarde nossos tokens de recuperação de senha referentes ao sistema de autenticação:

'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
'admins' => [
'provider' => 'admins',
'table' => 'admin_password_resets',
'expire' => 15,
],
'ads' => [
'provider' => 'ads',
'table' => 'ad_password_resets',
'expire' => 60,
],
],

Recomendo copiar as migrations “create_users_table” e “create_password_resets_table” para Admin e Ad.

Agora só precisamos iniciar nosso sistema de autenticação padrão Laravel usando o comando:

php artisan make:auth

Configurando nosso Login/Home redirect

Bom, para que nossa aplicação saiba “para onde ir” quando um usuário não-autenticado tentar acessar sua página home, teremos que configurar o método unauthenticated() em nosso app\Exceptions\Handler.php:

protected function unauthenticated(...)
{
...
$guard = array_get($exception->guards(), 0); return redirect()->guest(route("{$guard}.login"));
}

Agora precisamos configurar o método handle() do nosso app\Http\Middleware\RedirectIfAuthenticated.php para fazer o inverso: dizer ao Laravel “para onde ir” quando um usuário autenticado tentar acessar sua página login.

public function handle(...)
{
if (Auth::guard($guard)->check()) {
return redirect()->route("{$guard}.home");
}
return $next($request);
}

Lembrando que logo mais iremos configurar as rotas para user.*, admin.* e ad.*. Assim as configurações acima farão todo sentido.

Configurando controllers

Devemos lembrar sempre de utilizarmos os namespaces para cada tipo de autenticação na hora de criarmos nossos controllers, por exemplo:

php artisan make:controller User/HomeControllerphp artisan make:controller Admin/HomeControllerphp artisan make:controller Ad/HomeController

Bom, copie o conteúdo do arquivo app\Http\Controllers\HomeController.php criado automaticamente quando você executou o comando php artisan make:auth e cole em todos os controllers criados acima.

Note que você precisará alterar o namespace de cada HomeController, por exemplo:

<?phpnamespace App\Http\Controllers\User\Auth;ounamespace App\Http\Controllers\Admin\Auth;ounamespace App\Http\Controllers\Ad\Auth;

Feito isso, é hora de copiar a pasta app\Http\Controllers\Auth para as pastas app\Http\Controllers\User, app\Http\Controllers\Admin e app\Http\Controllers\Ad. Isso mesmo, clonar os controllers!

Na pasta Auth de cada namespace, User, Admin e Ad, iremos configurar nossos controllers de autenticação onde guard troquemos para o guard da autenticação.

ForgotPasswordController.php

use Illuminate\Support\Facades\Password;
...
class ForgotPasswordController extends Controller
{
use SendsPasswordResetEmails;
public function showLinkRequestForm()
{
return view('guard.auth.passwords.email');
}
public function broker()
{
return Password::broker('provider');
}
}

LoginController.php

use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
...
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/guard'; public function showLoginForm()
{
return view('guard.auth.login');
}
public function logout(Request $request)
{
$this->guard()->logout();
return redirect('/guard/login');
}
protected function guard()
{
return Auth::guard('guard');
}
}

RegisterController.php

use App\Guard;
use Illuminate\Support\Facades\Auth;
...
class RegisterController extends Controller
{
use RegistersUsers;
protected $redirectTo = '/guard'; public function showRegistrationForm()
{
return view('guard.auth.register');
}
protected function guard()
{
return Auth::guard('guard');
}
... protected function validator(array $data)
{
return Validator::make($data, [
...
'email' => 'required|email|max:255|unique:provider',
...
]);
}
protected function create(array $data)
{
return Guard::create([
...
]);
}
}

Note que temos acima um provider e, ao invés de utilizarmos, por exemplo, admin, utilizaremos admins. E assim será com os demais: user = users e ad = ads.

ResetPasswordController.php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Facades\Auth;
...
class ResetPasswordController extends Controller
{
use ResetsPasswords;
protected $redirectTo = '/guard'; public function showResetForm(Request $request, $token = null)
{
return view('guard.auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
public function broker()
{
return Password::broker('provider');
}
protected function guard()
{
return Auth::guard('guard');
}
}

Note que, para User, em protected $redirectTo = ‘/guard’; você pode até mudar para um nome mais familiar, como /myaccount.

Em ambos os controllers precisamos informar o guard para cada autenticação no método __construct():

public function __construct()
{
$this->middleware('guest:guard');
}

Pronto! Agora, pra finalizar esta parte dos controllers, iremos configurar nosso HomeController de cada namespace:

public function __construct()
{
$this->middleware('auth:guard');
}
public function index()
{
return view('guard.home');
}

Criando nossas views

Bom, o que iremos fazer aqui é quase o mesmo que fizemos anteriormente nos controllers: clonar tudo para cada namespace/guard da autenticação.

Vamos copiar a pasta resources\views\auth para resources\views\user\auth, resources\views\admin\auth e resources\views\ad\auth.

Feito isso, é hora de configurarmos as views para cada autenticação:

login.blade.php

<form class="form-horizontal" role="form" method="POST" action="{{ route('guard.login') }}">
...
<a class="btn btn-link" href="{{ route('guard.password.request')...
Forgot Your Password?
</a>

register.blade.php

<form class="form-horizontal" role="form" method="POST" action="{{ route('guard.register') }}">

passwords\email.blade.php

<form class="form-horizontal" role="form" method="POST" action="{{ route('guard.password.email') }}">

passwords\reset.blade.php

<form class="form-horizontal" role="form" method="POST" action="{{ route('guard.password.request') }}">

E é isso! Agora só precisamos criar uma view home.blade.php para cada uma dessas autenticações.

Definindo rotas

Vamos agora para a penúltima parte definir nossas rotas:

routes\web.php

<?phprequire 'auth/user.php';
require 'auth/admin.php';
require 'auth/ad.php';

routes\auth\admin.php

<?phpRoute::prefix('admin')->name('admin.')->namespace('Admin')->group(function () {
Auth::routes();
Route::get('home', 'HomeController@index')->name('home');
Route::middleware('auth:admin')->group(function () {
Route::get('another', 'AnotherController@index')->name('another');
});
});

Lembre-se de fazer o mesmo com User e Ad. Note que, para User, não é necessário o prefix. Caso contrário, a rota de login ficaria /users/login ao invés de apenas /login.

Configurando e-mail de recuperação de senha

Para que seja possível definirmos o envio de e-mails diferentes para cada tipo de autenticação, seja ela User, Admin ou Ad, utilizaremos as Notifications do Laravel.

Para criar nossa Notification será necessário o seguinte comando Artisan:

php artisan make:notification Admin/ResetPasswordNotification

Em app\Admin.php:

<?phpnamespace App;use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Notifications\Admin\ResetPasswordNotification;
class Admin extends Authenticatable
{
use Notifiable;
protected $guard = 'admin'; /**
* Send the password reset notification.
*
* @param string $token
* @return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
}

Em app\Notifications\Admin\ResetPasswordNotification.php:

<?phpclass ResetPasswordNotification extends Notification
{
...
private $token;
public function __construct($token)
{
$this->token = $token;
}
...
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Reset Password')
->greeting('Hello!')
->line('...')
->action('Reset Password', route('admin.password.reset', $this->token))
->line('...');
}
}

Lembre-se de fazer o mesmo para User e Ad. Note que, para User, não é necessário o protected $guard = ‘user’; no model App\User, pois este é o guard padrão configurado em config/auth.php.

Abaixo deixei alguns links que podem te ajudar em como trabalhar com autenticação no Laravel 5.4.

Renan Coelho

Written by

Desenvolvedor Web autodidata e apaixonado por tecnologia.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade