Una de las grandes ventajas de trabajar con Laravel es que podemos armarlo como más nos convenga o agrade, lo que lo hace flexible pero al mismo tiempo puede ser confuso por su variedad de paquetes y es por eso que en este tutorial aprenderás cómo instalar el sistema de autenticación Fortify con Bootstrap 5 en Laravel 9. Para este tutorial uso Laravel 9.19 el cual usa Vite de manera predeterminada. Sin más, manos a la obra.
Requisitos previos
- Contar con un entorno de desarrollo como XAMPP, Wamp o Laragon.
- Composer instalado globalmente en el sistema operativo.
- Node instalado.
1. Crear proyecto Laravel 9
Para crear un proyecto nuevo en Laravel 9 primero abre una terminal de comandos en la raíz de tu entorno de desarrollo y ejecuta la siguiente instrucción:
composer create-project laravel/laravel laravel-fortify-bootstrap-5
Ingresa a la carpeta del proyecto:
cd laravel-fortify-bootstrap-5
2. Instalar Bootstrap 5
Para instalar Bootstrap 5 en la terminal ejecuta los siguientes comandos:
npm i bootstrap --save-dev
npm install sass --save-dev
Desde tu editor de textos abre tu proyecto en Laravel 9 y cambia el nombre al archivo resources/css/app.css por resources/css/app.scss como se muestra aquí:
Y en ese mismo archivo app.scss importa Bootstrap 5 agregando la siguiente línea de código:
@import 'bootstrap/scss/bootstrap';
Haz lo mismo en el archivo resources/js/app.js agregando en él:
import * as bootstrap from 'bootstrap'
La versión de Laravel 9 que estoy usando para este tutorial incorpora por default Vite el cual tienes que configurar, para ello abre el archivo vite.config.js que se encuentra en la raíz del proyecto y cambia la referencia resources/css/app.css por resources/css/app.scss:
3. Crear y configurar base de datos
Para crear una base de datos para tu proyecto tienes que abrir la consola de MySQL para ello desde la terminal de comandos ejecuta la siguiente instrucción e ingresa tus credenciales:
mysql -u root -p
Ahora crea una nueva base de datos con el comando:
CREATE DATABASE laravel_fortify CHARACTER SET utf8 COLLATE utf8_spanish_ci;
Para salir de la consola de MySQL solo ejecuta:
exit
Ahora abre el archivo .env que se encuentra en la raíz del proyecto y agrega los datos de la nueva base de datos como el nombre, el usuario y la contraseña:
4. Instalar Laravel Fortify
Para instalar Fortify con Composer desde la terminal de comandos ejecuta la siguiente instrucción:
composer require laravel/fortify
Luego para que se publiquen los assets de Fortify:
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
Abre el archivo config/app.php y busca la sección Application Service Providers y agrega la siguiente línea de código:
App\Providers\FortifyServiceProvider::class
Corre las migraciones ejecutando desde la terminal el comando:
php artisan migrate
Ahora abre el archivo app/Providers/FortifyServiceProvider.php e importa el modelo User y la clase Hash:
use App\Models\User; use Illuminate\Support\Facades\Hash;
Para habilitar las vistas y la lógica de autenticación que usará Fortify busca el método boot() y agrega las siguientes líneas de código:
Fortify::loginView(function () { return view('auth.login'); }); Fortify::authenticateUsing(function (Request $request) { $user = User::where('email', $request->email)->first(); if ($user && Hash::check($request->password, $user->password)) { return $user; } }); Fortify::registerView(function () { return view('auth.register'); });
5. Crear vistas para autenticación
Para el layout crea el archivo resources/views/layouts/app.blade.php y dentro agrega las siguientes líneas de código:
<!doctype html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- CSRF Token --> <meta name="csrf-token" content="{{ csrf_token() }}"> <title>{{ config('app.name', 'Diario del Programador') }}</title> <!-- Fonts --> <link rel="dns-prefetch" href="//fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet"> <!-- Styles --> @vite(['resources/js/app.js', 'resources/css/app.scss']) </head> <body> <div id="app"> <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm"> <div class="container"> <a class="navbar-brand" href="{{ url('/') }}"> {{ config('app.name', 'Diario del Programador') }} </a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <!-- Right Side Of Navbar --> <ul class="navbar-nav"> <!-- Authentication Links --> @guest <li class="nav-item"> <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a> </li> @if (Route::has('register')) <li class="nav-item"> <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a> </li> @endif @else <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false"> {{ Auth::user()->name }} </button> <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1"> <li><a class="dropdown-item" href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">{{ __('Logout') }}</a></li> </ul> <form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none"> @csrf </form> </div> @endguest </ul> </div> </div> </nav> <main class="pt-4"> @yield('content') </main> </div> </body> </html>
Crea la carpeta resources/views/auth y dentro de ella los archivos login.blade.php y register.blade.php copia el código correspondiente en cada archivo:
Login.blade.php
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header">{{ __('Login') }}</div> <div class="card-body"> <form method="POST" action="{{ route('login') }}"> @csrf <div class="form-group row mb-3"> <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> <div class="col-md-6"> <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus> @error('email') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="form-group row mb-3"> <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label> <div class="col-md-6"> <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password"> @error('password') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="form-group row mb-3"> <div class="col-md-6 offset-md-4"> <div class="form-check"> <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}> <label class="form-check-label" for="remember"> {{ __('Remember Me') }} </label> </div> </div> </div> <div class="form-group row mb-0"> <div class="col-md-8 offset-md-4"> <button type="submit" class="btn btn-primary"> {{ __('Login') }} </button> @if (Route::has('password.request')) <a class="btn btn-link" href="{{ route('password.request') }}"> {{ __('Forgot Your Password?') }} </a> @endif </div> </div> </form> </div> </div> </div> </div> </div> @endsection
register.blade.php
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header">{{ __('Register') }}</div> <div class="card-body"> <form method="POST" action="{{ route('register') }}"> @csrf <div class="form-group row mb-3"> <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label> <div class="col-md-6"> <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus> @error('name') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="form-group row mb-3"> <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> <div class="col-md-6"> <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email"> @error('email') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="form-group row mb-3"> <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label> <div class="col-md-6"> <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password"> @error('password') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="form-group row mb-3"> <label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label> <div class="col-md-6"> <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password"> </div> </div> <div class="form-group row mb-0"> <div class="col-md-6 offset-md-4"> <button type="submit" class="btn btn-primary"> {{ __('Register') }} </button> </div> </div> </form> </div> </div> </div> </div> </div> @endsection
Ahora falta crear la vista del dashboard es la que verá el usuario una vez que se haya autenticado para ello crea el archivo resources/views/dashboard.blade.php y agrega las siguientes líneas de código:
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header"> Dashboard </div> <div class="card-body"> @if(session('status')) <div class="alert alert-success" role="alert"> {{session('status')}} </div> @endif You are logged in! </div> </div> </div> </div> </div> @endsection
6. Crear ruta
Abre el archivo routes/web.php y agrega la ruta para el dashboard el cual el middleware auth estará protegiendo la ruta para que solamente usuarios autenticados ingresen:
Route::get('/home', function () { return view('dashboard'); })->middleware('auth');
7. Probar sistema de autenticación con Fortify
Primero abre una terminal de comandos y ejecuta la instrucción:
npm i && npm run dev
Luego abre otra terminal y escribe el comando:
php artisan serve
Abre tu navegador web y ve a la dirección http://127.0.0.1:8000 se mostrará la vista de inicio de tu proyecto Laravel con el sistema de autenticación:
Ve al menú Register y para registrarte ingresa los datos que se te piden:
Te has registrado con éxito en el sistema:
Deslogueate del sistema y vuelve a ingresar a él, verás que el sistema de autenticación Laravel Fortify está funcionando correctamente.
Conclusión
En este tutorial aprendiste a cómo instalar el sistema de autenticación Fortify y Bootstrap 5 en Laravel 9. Así mismo si fue de ayuda te invito a compartirlo en tus redes sociales para llegar a más personas y si tienes dudas o comentarios déjalos en la caja de comentarios, estaré al pendiente de ellos. Te mando un saludo.
Repositorio GitHub del tutorial.
Referencias: Laravel Fortify Documentación.
Te puede interesar: Crear CRUD con Laravel 8 y Livewire.
Excelente, al grano! Epico!
Hola Plinio, gracias por visitar y comentar, me alegra mucho que este tutorial haya sido de ayuda, te mando un saludo!
Excelente aportación y mas para mi que voy iniciando con Laravel.
Hola Natnajera gracias por visitar y comentar, me alegra mucho saber que este tutorial fue de ayuda, te envío un saludo!