05 🔐 Verificación de Email Profesional - Laravel Mailable + Template HTML | Proyecto FullStack
Duración: 50 minDescripción
📚 LECCIÓN 05: VERIFICACIÓN DE EMAIL PROFESIONAL Y ENVÍO DE CONTRASEÑA TEMPORAL 📧
Esta lección cubre la implementación de la funcionalidad de envío de correos electrónicos profesionales en Laravel para el registro de nuevos usuarios, incluyendo contraseñas temporales y una plantilla HTML elegante.
1. Configuración de Entorno y Conectividad ⚙️
- 1.1. Virtual Host Local: Creación de un Virtual Host local para simular un entorno de producción con un dominio de prueba (e.g., sistema_de_parqueo.test), facilitando la experiencia de desarrollo [02:40].
- 1.2. Configuración de SMTP con Mailtrap: Integración de la plataforma Mailtrap para la captura y prueba de correos electrónicos en desarrollo. Se ajustan las credenciales SMTP en el archivo .env del proyecto [07:01].
- 1.3. Prueba de Conectividad: Se valida que la configuración del correo funcione correctamente utilizando la funcionalidad de restablecimiento de contraseña nativa de Laravel [08:21].
2. Desarrollo de la Funcionalidad de Envío de Correo 📨
- 2.1. Generación de Contraseña Temporal: En el UserController, antes de guardar el nuevo usuario, se genera una contraseña temporal aleatoria de ocho dígitos para enviarla por correo, manteniendo la contraseña encriptada en la base de datos [26:53].
- 2.2. Creación del Mailable de Registro: Se utiliza el comando php artisan make:mail para crear la clase RegistroUsuarioMail. Esta clase recibe los datos del usuario y la contraseña temporal en su constructor [31:22].
- 2.3. Lógica de Almacenamiento y Envío:
- Se implementa el código en el método store del UserController para guardar el usuario, asignarle un rol (assignRole), y enviar el Mailable al correo del nuevo usuario [44:32].
- Se añade un mensaje de flash para notificar al administrador que el usuario fue registrado correctamente y la contraseña fue enviada [47:57].
3. Diseño Profesional de la Plantilla de Correo 🎨
- 3.1. Creación de la Vista de Correo: Se crea la vista HTML (email_registro_usuario.blade.php) que contendrá el cuerpo del mensaje de bienvenida [34:04].
- 3.2. Estilo Elegante con HTML/CSS: Se mejora la plantilla del correo con estilos CSS en línea para dar una apariencia profesional, incluyendo la presentación clara de la contraseña temporal y un botón de "Iniciar Sesión" [40:05].
- 3.3. Contenido del Mensaje: El correo notifica al usuario su nueva cuenta, proporciona su contraseña temporal y lo obliga a cambiarla en su primer inicio de sesión por motivos de seguridad [42:30].
Contenido
Código fuente del email_registro_usuario.php
<!DOCTYPE html>
<html lang="es">
<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">
<title>Bienvenido al Sistema de Parqueo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
line-height: 1.6;
}
.email-container {
max-width: 600px;
margin: 0 auto;
background: white;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1);
animation: slideIn 0.6s ease-out;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.header {
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);
color: white;
padding: 40px 30px;
text-align: center;
position: relative;
}
.header::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="car" patternUnits="userSpaceOnUse" width="20" height="20"><circle cx="10" cy="10" r="1" fill="rgba(255,255,255,0.1)"/></pattern></defs><rect width="100" height="100" fill="url(%23car)"/></svg>');
}
.header h1 {
font-size: 28px;
font-weight: 700;
margin-bottom: 10px;
position: relative;
z-index: 1;
}
.header .subtitle {
font-size: 16px;
opacity: 0.9;
position: relative;
z-index: 1;
}
.car-icon {
font-size: 48px;
margin-bottom: 20px;
display: block;
position: relative;
z-index: 1;
}
.content {
padding: 40px 30px;
background: white;
}
.welcome-message {
font-size: 24px;
color: #2c3e50;
margin-bottom: 30px;
text-align: center;
font-weight: 600;
}
.info-card {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 15px;
padding: 25px;
margin: 25px 0;
border-left: 5px solid #007bff;
position: relative;
}
.password-section {
background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
border-radius: 15px;
padding: 25px;
margin: 25px 0;
text-align: center;
border: 2px dashed #f39c12;
position: relative;
}
.password-section::before {
content: '🔐';
position: absolute;
top: -15px;
left: 50%;
transform: translateX(-50%);
background: white;
padding: 10px;
border-radius: 50%;
font-size: 24px;
}
.password-value {
font-size: 32px;
font-weight: 900;
color: #e74c3c;
letter-spacing: 3px;
margin: 15px 0;
text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
}
.steps {
background: #f8f9ff;
border-radius: 15px;
padding: 25px;
margin: 25px 0;
}
.steps h3 {
color: #5a67d8;
margin-bottom: 20px;
font-size: 18px;
text-align: center;
}
.step {
display: flex;
align-items: center;
margin: 15px 0;
padding: 15px;
background: white;
border-radius: 10px;
border-left: 4px solid #5a67d8;
transition: transform 0.2s;
}
.step:hover {
transform: translateX(5px);
}
.step-number {
background: #5a67d8;
color: white;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
margin-right: 15px;
font-size: 14px;
}
.button {
display: inline-block;
background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
color: white;
padding: 15px 30px;
text-decoration: none;
border-radius: 50px;
font-weight: 600;
text-align: center;
margin: 20px 0;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(0, 123, 255, 0.3);
}
.button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0, 123, 255, 0.4);
text-decoration: none;
color: white;
}
.footer {
background: #2c3e50;
color: white;
padding: 30px;
text-align: center;
}
.footer p {
margin: 10px 0;
opacity: 0.8;
}
.security-note {
background: #d1ecf1;
border: 1px solid #bee5eb;
border-radius: 10px;
padding: 20px;
margin: 20px 0;
color: #0c5460;
}
.security-note strong {
color: #0c5460;
}
@media (max-width: 600px) {
.email-container {
margin: 10px;
border-radius: 15px;
}
.header, .content, .footer {
padding: 20px;
}
.password-value {
font-size: 24px;
letter-spacing: 2px;
}
}
</style>
</head>
<body>
<div class="email-container">
<div class="header">
<div class="car-icon">🚗</div>
<h1>Sistema de Parqueo</h1>
</div>
<div class="content">
<div class="welcome-message">
¡Hola {{ $usuario->nombres }} {{ $usuario->apellidos }}!
</div>
<div class="info-card">
<p style="margin-bottom: 15px; color: #2c3e50; font-size: 16px;">
Tu cuenta ha sido creada exitosamente en nuestro sistema de parqueo.
Ahora formas parte de nuestra plataforma de gestión.
</p>
</div>
<div class="password-section">
<h3 style="color: #e67e22; margin-bottom: 10px;">Tu Contraseña Temporal</h3>
<div class="password-value">{{ $passwordTemporal }}</div>
<p style="color: #d68910; font-weight: 500; margin-top: 10px;">
Guarda esta contraseña en un lugar seguro
</p>
</div>
<div class="steps">
<h3>Pasos para acceder al sistema:</h3>
<div class="step">
<div class="step-number">1</div>
<div>
<strong>Inicia sesión</strong><br>
<span style="color: #666;">Usa tu email y la contraseña temporal</span>
</div>
</div>
<div class="step">
<div class="step-number">2</div>
<div>
<strong>Cambia tu contraseña</strong><br>
<span style="color: #666;">Crea una contraseña personal y segura</span>
</div>
</div>
</div>
<div style="text-align: center;">
<a href="{{ url('/login') }}" class="button">
🔓 Iniciar Sesión
</a>
</div>
<div class="security-note">
<strong>📋 Datos de acceso:</strong><br>
<strong>Email:</strong> {{ $usuario->email }}<br>
<strong>Contraseña temporal:</strong> {{ $passwordTemporal }}<br><br>
<strong>⚠️ Importante:</strong> Por seguridad, deberás cambiar esta contraseña en tu primer acceso al sistema.
</div>
</div>
<div class="footer">
<p><strong>Sistema de Parqueo Profesional</strong></p>
<p style="font-size: 12px; margin-top: 15px;">
Si no solicitaste esta cuenta, puedes ignorar este mensaje.
</p>
</div>
</div>
</body>
</html>