1. Seguridad
  2. Verificación de Correo Electrónico

Introducción

Muchas aplicaciones web requieren que los usuarios verifiquen sus direcciones de correo electrónico antes de usar la aplicación. En lugar de obligarte a implementar esta característica manualmente para cada aplicación que crees, Laravel proporciona servicios integrados convenientes para enviar y verificar solicitudes de verificación de correo electrónico.

Nota ¿Quieres empezar rápido? Instala uno de los paquetes iniciales de aplicaciones Laravel en una nueva aplicación Laravel. Los paquetes iniciales se encargarán de generar toda la estructura de tu sistema de autenticación, incluido el soporte para la verificación de correo electrónico.

Preparación del Modelo

Antes de comenzar, verifica que tu modelo App\Models\User implemente el contrato Illuminate\Contracts\Auth\MustVerifyEmail:

<?php
 
namespace App\Models;
 
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
 
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
 
// ...
}

Una vez que esta interfaz se haya agregado a tu modelo, los usuarios recién registrados recibirán automáticamente un correo electrónico que contiene un enlace de verificación de correo electrónico. Como puedes ver al examinar el App\Providers\EventServiceProvider de tu aplicación, Laravel ya contiene un escuchador SendEmailVerificationNotification que está adjunto al evento Illuminate\Auth\Events\Registered. Este escuchador de eventos enviará el enlace de verificación de correo electrónico al usuario.

Si estás implementando el registro manualmente en tu aplicación en lugar de usar un paquete inicial, debes asegurarte de estar despachando el evento Illuminate\Auth\Events\Registered después de que se complete el registro del usuario:

use Illuminate\Auth\Events\Registered;
 
event(new Registered($user));

Preparación de la Base de Datos

A continuación, tu tabla users debe contener una columna email_verified_at para almacenar la fecha y hora en que se verificó la dirección de correo electrónico del usuario. Por defecto, la migración de la tabla users incluida con el framework Laravel ya incluye esta columna. Así que todo lo que necesitas hacer es ejecutar tus migraciones de base de datos:

php artisan migrate

Enrutamiento

Para implementar correctamente la verificación de correo electrónico, será necesario definir tres rutas. Primero, se necesitará una ruta para mostrar un aviso al usuario indicándole que debe hacer clic en el enlace de verificación de correo electrónico en el correo electrónico de verificación que Laravel le envió después del registro.

En segundo lugar, se necesitará una ruta para manejar las solicitudes generadas cuando el usuario hace clic en el enlace de verificación de correo electrónico en el correo electrónico.

En tercer lugar, se necesitará una ruta para reenviar un enlace de verificación si el usuario pierde accidentalmente el primer enlace de verificación.

El Aviso de Verificación por Correo Electrónico

Como se mencionó anteriormente, se debe definir una ruta que devuelva una vista indicando al usuario que haga clic en el enlace de verificación de correo electrónico que se le envió por correo electrónico después del registro de Laravel. Esta vista se mostrará a los usuarios cuando intenten acceder a otras partes de la aplicación sin verificar primero su dirección de correo electrónico. Recuerda, el enlace se envía automáticamente al usuario siempre que tu modelo App\Models\User implemente la interfaz MustVerifyEmail:

Route::get('/email/verify', function () {
return view('auth.verify-email');
})->middleware('auth')->name('verification.notice');

La ruta que devuelve el aviso de verificación de correo electrónico debe tener el nombre verification.notice. Es importante que la ruta tenga asignado este nombre exacto, ya que el middleware verified incluido con Laravel se redirigirá automáticamente a este nombre de ruta si un usuario no ha verificado su dirección de correo electrónico.

Nota Cuando implementas la verificación de correo electrónico manualmente, debes definir el contenido de la vista de notificación de verificación tú mismo. Si deseas un andamiaje que incluya todas las vistas de autenticación y verificación necesarias, echa un vistazo a los paquetes iniciales de aplicaciones Laravel.

El Manejador de Verificación por Correo Electrónico

A continuación, debemos definir una ruta que maneje las solicitudes generadas cuando el usuario hace clic en el enlace de verificación de correo electrónico que se le envió por correo electrónico. Esta ruta debe tener el nombre verification.verify y estar asignada a los middlewares auth y signed:

use Illuminate\Foundation\Auth\EmailVerificationRequest;
 
Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
$request->fulfill();
 
return redirect('/home');
})->middleware(['auth', 'signed'])->name('verification.verify');

Antes de continuar, echemos un vistazo más de cerca a esta ruta. En primer lugar, notarás que estamos utilizando un tipo de solicitud EmailVerificationRequest en lugar de la típica instancia de Illuminate\Http\Request. La EmailVerificationRequest es una solicitud de formulario que se incluye con Laravel. Esta solicitud se encargará automáticamente de validar los parámetros id y hash de la solicitud.

A continuación, podemos proceder directamente a llamar al método fulfill en la solicitud. Este método llamará al método markEmailAsVerified en el usuario autenticado y despachará el evento Illuminate\Auth\Events\Verified. El método markEmailAsVerified está disponible para el modelo App\Models\User predeterminado a través de la clase base Illuminate\Foundation\Auth\User. Una vez que se haya verificado la dirección de correo electrónico del usuario, puedes redirigirlo donde desees.

Reenviar el Correo de Verificación

En ocasiones, un usuario puede perder o eliminar accidentalmente el correo electrónico de verificación de la dirección de correo electrónico. Para acomodar esto, es posible que desees definir una ruta que permita al usuario solicitar que se reenvíe el correo electrónico de verificación. Luego puedes realizar una solicitud a esta ruta colocando un simple botón de envío de formulario dentro de tu vista de notificación de verificación de correo electrónico:

use Illuminate\Http\Request;
 
Route::post('/email/verification-notification', function (Request $request) {
$request->user()->sendEmailVerificationNotification();
 
return back()->with('message', 'Verification link sent!');
})->middleware(['auth', 'throttle:6,1'])->name('verification.send');

Protección de Rutas

Se puede utilizar el middleware de ruta para permitir solo a los usuarios verificados acceder a una ruta específica. Laravel incluye un alias de middleware verified, que es un alias de la clase Illuminate\Auth\Middleware\EnsureEmailIsVerified. Dado que este middleware ya está registrado en el kernel HTTP de tu aplicación, todo lo que necesitas hacer es adjuntar el middleware a una definición de ruta. Por lo general, este middleware se empareja con el middleware auth:

Route::get('/profile', function () {
// Solo los usuarios verificados pueden acceder a esta ruta...
})->middleware(['auth', 'verified']);

Si un usuario no verificado intenta acceder a una ruta a la que se le haya asignado este middleware, será redirigido automáticamente a la ruta con nombre verification.notice.

Personalización

Personalización del Correo de Verificación

Aunque la notificación de verificación de correo electrónico predeterminada debería satisfacer los requisitos de la mayoría de las aplicaciones, Laravel te permite personalizar cómo se construye el mensaje de correo electrónico de verificación.

Para comenzar, pasa un cierre al método toMailUsing proporcionado por la notificación Illuminate\Auth\Notifications\VerifyEmail. El cierre recibirá la instancia del modelo notificable que está recibiendo la notificación, así como la URL de verificación de correo electrónico firmada que el usuario debe visitar para verificar su dirección de correo electrónico. El cierre debe devolver una instancia de Illuminate\Notifications\Messages\MailMessage. Por lo general, debes llamar al método toMailUsing desde el método boot de la clase App\Providers\AuthServiceProvider de tu aplicación:

use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
 
/**
* Registra cualquier servicio de autenticación / autorización.
*/
public function boot(): void
{
// ...
 
VerifyEmail::toMailUsing(function (object $notifiable, string $url) {
return (new MailMessage)
->subject('Verify Email Address')
->line('Click the button below to verify your email address.')
->action('Verify Email Address', $url);
});
}

Nota Para obtener más información sobre notificaciones de correo electrónico, consulta la documentación de notificaciones de correo electrónico.

Eventos

Cuando usas los paquetes iniciales de aplicaciones Laravel, Laravel despacha eventos durante el proceso de verificación de correo electrónico. Si estás manejando manualmente la verificación de correo electrónico para tu aplicación, es posible que desees despachar manualmente estos eventos después de que se complete la verificación. Puedes adjuntar escuchadores a estos eventos en la clase EventServiceProvider de tu aplicación:

use App\Listeners\LogVerifiedUser;
use Illuminate\Auth\Events\Verified;
 
/**
* Las asignaciones de escuchadores de eventos para la aplicación.
*
* @var array
*/
protected $listen = [
Verified::class => [
LogVerifiedUser::class,
],
];