11: Conoce y usa Laravel Jetstream
11: Conoce y usa Laravel Jetstream
Introducción
En este tutorial exploraremos Laravel Jetstream, una herramienta poderosa que hemos instalado en nuestro proyecto y que nos proporciona un sistema completo de autenticación, gestión de perfiles y una base sólida para construir aplicaciones modernas. Aprenderemos cómo funciona, qué componentes genera y cómo podemos empezar a personalizarlos.
¿Qué es Laravel Jetstream?
Laravel Jetstream es un paquete oficial de Laravel que proporciona un scaffolding de autenticación moderno y completo. Incluye:
Registro e inicio de sesión de usuarios
Verificación de email
Restablecimiento de contraseña
Autenticación de dos factores (2FA)
Gestión de sesiones del navegador
Gestión de perfiles con foto de perfil
Gestión de equipos (opcional)
Tokens API (opcional)
Jetstream soporta dos stacks principales:
Livewire: Para aplicaciones con interacción en el backend
Inertia.js: Para aplicaciones SPA con Vue.js o React
Nosotros utilizaremos Inertia con Vue.js, que es el stack que elegimos en el tutorial anterior.
Paso 1: Instalar Jetstream (si no lo has hecho)
Si aún no tienes Jetstream instalado, ejecuta:
composer require laravel/jetstreamLuego, instálalo con el stack Inertia:
php artisan jetstream:install inertiaInstala las dependencias NPM y compila:
npm install
npm run buildPaso 2: Ejecutar las migraciones
Jetstream añade nuevas tablas necesarias para la autenticación y gestión de usuarios:
php artisan migrateLas tablas que Jetstream crea incluyen:
users- Tabla de usuariospassword_reset_tokens- Tokens para restablecimiento de contraseñasessions- Sesiones de usuariopersonal_access_tokens- Tokens de API (Laravel Sanctum)failed_jobs- Registro de trabajos fallidos
Paso 3: Explorar la estructura generada
Jetstream genera una gran cantidad de archivos y componentes. Vamos a revisar los más importantes:
3.1 Estructura de Backend
app/
├── Actions/
│ ├── Fortify/
│ │ ├── CreateNewUser.php # Lógica para crear usuarios
│ │ ├── UpdateUserPassword.php # Actualizar contraseña
│ │ ├── UpdateUserProfileInformation.php # Actualizar perfil
│ │ └── ...
│ └── Jetstream/
│ ├── AddTeamMember.php # Agregar miembros a equipos
│ ├── CreateTeam.php # Crear equipos
│ ├── DeleteTeam.php # Eliminar equipos
│ └── ...
├── Http/
│ ├── Controllers/
│ │ └── ProfileController.php # Gestión del perfil
│ ├── Middleware/
│ │ └── ...
│ └── ...3.2 Estructura de Frontend
resources/
├── js/
│ ├── Components/
│ │ ├── ApplicationLogo.vue # Logo de la aplicación
│ │ ├── AuthenticationCard.vue # Tarjeta de autenticación
│ │ ├── Button.vue # Botón reutilizable
│ │ ├── Input.vue # Campo de entrada
│ │ ├── InputError.vue # Mensaje de error
│ │ ├── Label.vue # Etiqueta de formulario
│ │ ├── Modal.vue # Ventana modal
│ │ ├── NavLink.vue # Enlace de navegación
│ │ └── ...
│ ├── Layouts/
│ │ └── AppLayout.vue # Layout principal
│ ├── Pages/
│ │ ├── Dashboard.vue # Página del dashboard
│ │ ├── Profile/
│ │ │ ├── Show.vue # Ver perfil
│ │ │ ├── Partials/
│ │ │ │ ├── UpdateProfileInformationForm.vue
│ │ │ │ ├── UpdatePasswordForm.vue
│ │ │ │ ├── TwoFactorAuthenticationForm.vue
│ │ │ │ └── LogoutOtherBrowserSessionsForm.vue
│ │ ├── Auth/
│ │ │ ├── Login.vue # Página de login
│ │ │ ├── Register.vue # Página de registro
│ │ │ ├── ForgotPassword.vue # Recuperar contraseña
│ │ │ ├── ResetPassword.vue # Restablecer contraseña
│ │ │ ├── VerifyEmail.vue # Verificar email
│ │ │ └── TwoFactorChallenge.vue # Desafío 2FA
│ │ └── Welcome.vue # Página de bienvenida
│ └── app.js # Punto de entrada de la aplicaciónPaso 4: Configuración del archivo .env
Jetstream utiliza algunas variables de entorno adicionales. Asegúrate de tener estas configuraciones en tu .env:
# Configuración de la aplicación
APP_NAME="Mi Portafolio"
APP_URL=http://localhost:8000
# Configuración de base de datos
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=portfolio_cpa
DB_USERNAME=root
DB_PASSWORD=
# Configuración de Jetstream
JETSTREAM_STACK=inertia
JETSTREAM_FEATURES=profile,api,teamsPaso 5: Comprender las rutas
Jetstream configura automáticamente las rutas de autenticación. Revisa routes/web.php:
<?php
use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route;
// Ruta de bienvenida
Route::get('/', function () {
return inertia('Welcome');
})->name('home');
// Rutas de autenticación (manejadas por Fortify)
// No es necesario definirlas manualmente
// Dashboard (protegido)
Route::middleware(['auth:sanctum', 'verified'])->group(function () {
Route::get('/dashboard', function () {
return inertia('Dashboard');
})->name('dashboard');
});
// Perfil de usuario (protegido)
Route::group(['middleware' => 'auth'], function () {
Route::get('/user/profile', [ProfileController::class, 'show'])
->name('profile.show');
});Paso 6: Probar el sistema de autenticación
6.1 Registrar un usuario
Visita
http://localhost:8000Haz clic en Register
Completa el formulario con:
Name: Tu nombre
Email: test@example.com
Password: contraseña segura (mínimo 8 caracteres)
Confirm Password: confirmar contraseña
Haz clic en Register
6.2 Iniciar sesión
Ve a la página de login
Ingresa tus credenciales
Serás redirigido al Dashboard
6.3 Explorar el perfil
Una vez autenticado, ve a Profile en el menú de usuario. Aquí podrás:
Actualizar información de perfil: Nombre, email, foto
Cambiar contraseña
Configurar autenticación de dos factores
Gestionar sesiones activas
Paso 7: Personalizar la página de bienvenida
La página de bienvenida (resources/js/Pages/Welcome.vue) es donde comienza tu aplicación. Vamos a simplificarla y personalizarla:
<template>
<div class="min-h-screen bg-gray-100">
<nav class="bg-white border-b border-gray-100">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16">
<!-- Logo -->
<div class="flex items-center">
<ApplicationLogo class="w-8 h-8" />
<span class="ml-2 text-xl font-semibold">Mi Portafolio</span>
</div>
<!-- Enlaces de autenticación -->
<div class="flex items-center space-x-4">
<Link v-if="!$page.props.auth.user" :href="route('login')" class="text-gray-700 hover:text-gray-900">
Iniciar Sesión
</Link>
<Link v-if="!$page.props.auth.user" :href="route('register')" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">
Registrarse
</Link>
<div v-else class="flex items-center space-x-3">
<Link :href="route('dashboard')" class="text-gray-700 hover:text-gray-900">
Dashboard
</Link>
<Link :href="route('profile.show')" class="text-gray-700 hover:text-gray-900">
Perfil
</Link>
<button @click="logout" class="text-gray-700 hover:text-gray-900">
Cerrar Sesión
</button>
</div>
</div>
</div>
</div>
</nav>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-xl sm:rounded-lg p-8">
<h1 class="text-4xl font-bold text-gray-900">
¡Bienvenido a Mi Portafolio!
</h1>
<p class="mt-4 text-lg text-gray-600">
Este es el inicio de tu portafolio profesional con Laravel Jetstream e Inertia.js.
</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { Link } from '@inertiajs/vue3';
import { router } from '@inertiajs/vue3';
import ApplicationLogo from '@/Components/ApplicationLogo.vue';
const logout = () => {
router.post(route('logout'));
};
</script>Paso 8: Entender el flujo de autenticación
8.1 Registro de usuario
El usuario envía el formulario de registro
CreateNewUseraction valida y crea el usuarioLaravel Fortify maneja la autenticación
El usuario es redirigido al dashboard
8.2 Inicio de sesión
El usuario envía credenciales
Fortify valida las credenciales
Se crea la sesión
El usuario es redirigido al dashboard
8.3 Protección de rutas
Las rutas que requieren autenticación usan el middleware auth:
Route::middleware(['auth:sanctum', 'verified'])->group(function () {
Route::get('/dashboard', function () {
return inertia('Dashboard');
})->name('dashboard');
});Paso 9: Agregar funcionalidad de verificación de email
Para habilitar la verificación de email, asegúrate de que estas configuraciones estén activas:
# En .env
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=tu_usuario
MAIL_PASSWORD=tu_contraseña
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@example.com
MAIL_FROM_NAME="${APP_NAME}"En el modelo User, implementa MustVerifyEmail:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Sanctum\HasApiTokens;
use Laravel\Jetstream\HasProfilePhoto;
class User extends Authenticatable implements MustVerifyEmail
{
use HasApiTokens, HasProfilePhoto;
// ...
}Paso 10: Personalizar componentes de Jetstream
Jetstream te permite personalizar cada uno de sus componentes. Algunas personalizaciones comunes:
10.1 Cambiar colores
Modifica el archivo tailwind.config.js:
export default {
theme: {
extend: {
colors: {
primary: '#4F46E5', // Tu color personalizado
secondary: '#7C3AED',
},
},
},
}10.2 Modificar el layout
Edita resources/js/Layouts/AppLayout.vue para cambiar la estructura de la aplicación:
<template>
<div class="min-h-screen bg-gray-100">
<header class="bg-white shadow">
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<h1 class="text-3xl font-bold text-gray-900">
<slot name="header" />
</h1>
</div>
</header>
<main class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<slot />
</div>
</main>
</div>
</template>10.3 Agregar nuevos campos al registro
Modifica app/Actions/Fortify/CreateNewUser.php para agregar campos adicionales:
public function create(array $input)
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'phone' => ['required', 'string', 'max:20'], // Nuevo campo
])->validate();
return User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
'phone' => $input['phone'], // Nuevo campo
]);
}Solución de problemas comunes
Error: "The manifest.json does not exist"
Solución: Compila los assets:
npm run buildError: "Unable to locate a class or view"
Solución: Verifica que las rutas y los nombres de las vistas coincidan.
Error: "419 Page Expired"
Solución: Asegúrate de que el token CSRF esté incluido en las peticiones:
<template>
<form @submit.prevent="submit">
<!-- El token CSRF se maneja automáticamente con Inertia -->
</form>
</template>Problema con las dependencias npm
Si encuentras errores con dependencias legacy:
npm install --legacy-peer-deps
npm run devResumen
✅ Exploramos la estructura generada por Laravel Jetstream
✅ Aprendimos a usar el sistema de autenticación
✅ Personalizamos la página de bienvenida
✅ Entendimos el flujo de autenticación
✅ Modificamos componentes y agregamos nuevos campos
¡Excelente trabajo! Ahora tienes un conocimiento sólido de cómo funciona Laravel Jetstream y cómo puedes personalizarlo para tu portafolio. Con esta base, puedes comenzar a construir las funcionalidades específicas de tu aplicación.
Recursos adicionales
¿Tienes preguntas sobre Jetstream? Recuerda que la documentación oficial y los videos del curso pueden ayudarte a resolver cualquier duda
Comentarios
Publicar un comentario