There are many aspects in implementation of authentication. Let’s consider them one be one.
Registration
We should have a form for signing up. So, your Blade-template should contain something like this:
<form method="post">
@csrf
<div>
<label for="name">Name:</label>
<input id="name" type="text" name="name" value="{{ old('name') }}">
</div>
<div>
<label for="email">Email:</label>
<input id="email" type="email" name="email" value="{{ old('email') }}">
</div>
<div>
<label for="password">Password:</label>
<input id="password" name="password" type="password">
</div>
<div>
<label for="confirm-password">Confirm password:</label>
<input id="confirm-password" name="password_confirmation" type="password">
</div>
<div>
<button>Sign up</button>
</div>
</form>
Let’s add a route and a controller for this operation:
# routes/web.php
Route::get('register', [RegisterController::class, 'showRegistrationForm'])
->name('register');
We will also add the guest middleware to this controller so authenticated users won’t have access to it.
# app/Http/Controllers/Auth/RegisterController.php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
class RegisterController extends Controller implements HasMiddleware
{
public static function middleware(): array
{
return ['guest'];
}
public function showRegistrationForm(): View
{
return view('auth.register');
}
}
And let’s add a method for receiving and validation data:
# routes/web.php
Route::post('register', [RegisterController::class, 'register']);
# app/Http/Controllers/Auth/RegisterController.php
class RegisterController extends Controller implements HasMiddleware
{
//...
public function register(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8|confirmed',
]);
$user = User::create([
'name' => $validated['name'],
'email' => $validated['email'],
'password' => Hash::make($validated['password']),
]);
event(new Registered($user));
Auth::login($user);
return redirect()->route('dashboard');
}
}
Login
First of all, we should receive login and password from the user. It means that we should have a form:
<form method="post">
@csrf
<div>
<label for="email">Email:</label>
<input id="email" type="email" name="email" value="{{ old('email') }}">
</div>
<div>
<label for="password">Password:</label>
<input id="password" name="password" type="password">
</div>
<div>
Remember me?
<input type="checkbox" name="remember" value="1">
</div>
<div>
<button>Log in</button>
</div>
</form>
And we should add a route and a controller for this operation:
# routes/web.php
Route::get('login', [LoginController::class, 'showLoginForm'])->name('login');
# app/Http/Controllers/Auth/LoginController.php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
class LoginController extends Controller
{
public function showLoginForm()
{
return view('auth.login');
}
}
And now we should have a method for receiving data:
# routes/web.php
Route::post('login', [LoginController::class, 'login']);
class LoginController extends Controller
{
// ...
public function login(Request $request)
{
$credentials = $request->validate([
'email' => 'required|string|email',
'password' => 'required|string',
]);
if (Auth::attempt($credentials, $request->boolean('remember'))) {
// Prevent session fixation:
$request->session()->regenerate();
return redirect()->intended();
}
throw ValidationException::withMessages([
'auth' => [trans('auth.failed')],
]);
}
}
Or we can redirect a user without using the exception object:
return back()->withErrors([
'auth' => trans('auth.failed'),
]);
Logout
Let’s add some middlewares:
class LoginController extends Controller implements HasMiddleware
{
public static function middleware(): array
{
return [
new Middleware('guest', except: ['logout']),
new Middleware('auth', only: ['logout'])
];
}
// ...
}
A route and a method:
# routes/web.php
Route::post('logout', [LoginController::class, 'logout'])->name('logout');
<?php
namespace App\Http\Controllers\Auth;
class LoginController extends Controller implements HasMiddleware
{
// ...
public function logout(): RedirectResponse
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
Example of how to implement the logout button:
<a href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
@csrf
</form>
Andrew Dorokhov