Laravel Passwordless Authentication Part 2
In the second part of this tutorial, we will add the controller which will hold the functions for storing and authenticating users, and we will add the base layout with the navigation menu.
Create the controller
First, let's create the 'UserController' here we have the functions for storing and authenticating users.
<?php
namespace App\Http\Controllers;
use App\Models\User;
use App\Mail\LoginLink;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Mail;
class UserController extends Controller
{
//
public function login()
{
return view('auth.login');
}
public function auth(Request $request)
{
$request->validate([
'email' => ['required', 'email', Rule::exists(User::class, 'email')]
]);
Mail::to($request->email)->send(new LoginLink($request->email));
return redirect()->back()->with([
'success' => 'Your login link has been sent please check your mail box'
]);
}
public function register()
{
return view('auth.register');
}
public function store(Request $request)
{
$request->validate([
'name' => ['required','max:255'],
'email' => ['required', 'email', 'unique:users']
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email
]);
Mail::to($request->email)->send(new LoginLink($user->email));
return redirect()->back()->with([
'success' => 'Your login link has been sent please check your mail box'
]);
}
public function logout()
{
auth()->logout();
return redirect()->route('login');
}
public function session($email)
{
$user = User::whereEmail($email)->first();
auth()->login($user);
return redirect()->route('home');
}
}
Create the base layout
Inside views let's create a new folder 'layouts' inside let's add a new file 'app.blade.php' inside we have CSS & JS links.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- Font Awesome -->
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
rel="stylesheet"
/>
<!-- Google Fonts -->
<link
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
rel="stylesheet"
/>
<!-- MDB -->
<link
href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.4.2/mdb.min.css"
rel="stylesheet"
/>
<title>Laravel Password Less Auth</title>
</head>
<body class="bg-light">
@include('layouts.navbar')
<div class="container">
@yield('content')
</div>
<!-- MDB -->
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.4.2/mdb.min.js"
></script>
</body>
</html>
Create the navbar menu
Next, let's add a new file 'navbar.blade.php' Inside we have the navigation menu.
<!-- Navbar -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<!-- Container wrapper -->
<div class="container-fluid">
<!-- Toggle button -->
<button
class="navbar-toggler"
type="button"
data-mdb-toggle="collapse"
data-mdb-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<i class="fas fa-bars"></i>
</button>
<!-- Collapsible wrapper -->
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- Navbar brand -->
<a class="navbar-brand mt-2 mt-lg-0" href="{{route('home')}}">
Laravel Password Less Auth
</a>
<!-- Left links -->
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="{{route('home')}}">
<i class="fas fa-home"></i> Home
</a>
</li>
@guest
<li class="nav-item">
<a class="nav-link" href="{{route('login')}}">
<i class="fas fa-sign-in"></i> Login
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{route('register')}}">
<i class="fas fa-user-plus"></i> Register
</a>
</li>
@endguest
</ul>
<!-- Left links -->
</div>
<!-- Collapsible wrapper -->
<!-- Right elements -->
@auth
<div class="d-flex align-items-center">
<!-- Avatar -->
<div class="dropdown">
<a
class="dropdown-toggle d-flex align-items-center hidden-arrow"
href="#"
id="navbarDropdownMenuAvatar"
role="button"
data-mdb-toggle="dropdown"
aria-expanded="false"
>
<img
src="https://mdbcdn.b-cdn.net/img/new/avatars/2.webp"
class="rounded-circle"
height="25"
alt="Black and White Portrait of a Man"
loading="lazy"
/>
</a>
<ul
class="dropdown-menu dropdown-menu-end"
aria-labelledby="navbarDropdownMenuAvatar"
>
<li>
<a class="dropdown-item" href="#">{{auth()->user()->name}}</a>
</li>
<li>
<form id="formLogout" action="{{route('logout')}}" method="post">
@csrf
</form>
<a class="dropdown-item" href="#"
onclick="document.getElementById('formLogout').submit();">Logout</a>
</li>
</ul>
</div>
</div>
@endauth
<!-- Right elements -->
</div>
<!-- Container wrapper -->
</nav>
<!-- Navbar -->
Display flash messages
To display validation errors and flash messages let's create a new file 'alerts.blade.php'.
NB: all the files are inside the layouts folder.
@if ($errors->any())
@foreach ($errors->all() as $error)
<div class="alert alert-danger">
{{$error}}
</div>
@endforeach
@endif
@if (session()->has('success'))
<div class="alert alert-success">
{{session()->get('success')}}
</div>
@endif