En esta entrada vemos cómo banear usuarios en Laravel haciendo uso de Laravel Breeze, pero sería completamente funcional con Laravel Fortify u otras herramientas de autenticación.
Existen varias dependencias para banear usuarios en Laravel, en nuestro vamos a utilizar Laravel Ban, que, aunque para mi gusto falta darle una vuelta de tuerca al sistema de autenticación a través de las rutas y algún detalle más, lo que ofrece lo hace muy bien y no es poco.
Instalar Laravel Ban
composer require cybercog/laravel-ban
Publicar migraciones y configuración
El siguiente comando publicará la migración para la tabla de bans necesaria para este package y el archivo de configuración para realizar ajustes adicionales.
php artisan vendor:publish --provider="Cog\Laravel\Ban\Providers\BanServiceProvider"La migración para la tabla bans luce de la siguiente forma.
<?php
/*
* This file is part of Laravel Ban.
*
* (c) Anton Komarev <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBansTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
Schema::create('bans', function (Blueprint $table) {
$table->increments('id');
$table->morphs('bannable');
$table->nullableMorphs('created_by');
$table->text('comment')->nullable();
$table->timestamp('expired_at')->nullable();
$table->softDeletes();
$table->timestamps();
$table->index('expired_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('bans');
}
}Relaciones polimórficas para múltiples modelos.
Columna comment para almacenar el motivo.
Fecha de expiración, si es null nunca expirará.
Ahora abre el archivo de configuración config/ban.php y define la clave redirect_url por una url válida.
<?php
/*
* This file is part of Laravel Ban.
*
* (c) Anton Komarev <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
return [
/*
|--------------------------------------------------------------------------
| Ban Database Migrations
|--------------------------------------------------------------------------
|
| Determine if default package migrations should be registered.
| Set value to `false` when using customized migrations.
|
*/
'load_default_migrations' => true,
/*
|---------------------------------------------------------------------------
| URL to redirect banned user to
|---------------------------------------------------------------------------
|
| Provide a url, this is where a banned user will be redirected to
| by the middleware.
|
| For example:
|
| 'redirect_url' => route('banned.user'),
|
| or
|
| 'redirect_url' => '/user/banned',
|
| Leaving the value as null will result in a redirect "back".
|
*/
"redirect_url" => "/banned",
];Actualiza tu migración de usuarios
Para finalizar la configuración, es necesario actualizar la tabla de usuarios añadiendo una columna llamada banned_at de la siguiente forma.
php artisan make:migration add_banned_at_column_to_users_table<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddBannedAtColumnToUsersTable extends Migration
{
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->timestamp('banned_at')->nullable();
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('banned_at');
});
}
}Banear usuarios en Laravel
Para banear nuestro primer usuario simplemente debemos hacer lo siguiente.
<?php
Route::get("/ban-user", function () {
$user = \App\Models\User::first();
return tap($user)->ban([
"comment" => "Mala conducta",
"expired_at" => "+1 month",
]);
});El método anterior habrá baneado al primer usuario de la tabla users durante 1 mes.
Proteger las rutas de los usuarios baneados
Por defecto este package no aplica lógica alguna en el sistema de autenticación de forma directa, pero nos ofrece un Middleware que podemos utilizar para realizar el trabajo.
Para ello, abre el archivo app/Http/Kernel.php y añade la siguiente línea a la clave $routeMiddleware.
<?php
'forbid-banned-user' => \Cog\Laravel\Ban\Http\Middleware\ForbidBannedUser::class,Ahora, vamos a abrir el archivo de rutas web.php para actualizar el código por el siguiente.
<?php
use Illuminate\Support\Facades\Route;
use App\Models\User;
/**
* Banear usuarios
*/
Route::get("/ban-user", function () {
$user = User::first();
return tap($user)->ban([
"comment" => "Mala conducta",
"expired_at" => "+1 month",
]);
});
/**
* Rutas protegidas de usuarios baneados
*/
Route::group(["middleware" => ["auth", "forbid-banned-user"]], function () {
Route::get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
});
/**
* Ruta para mostrar información a los usuarios baneados
*/
Route::view("/banned", "banned");
require __DIR__.'/auth.php';Vista para los usuarios baneados
Ahora vamos a crear el archivo banned.blade.php para que los usuarios baneados sepan que están baneados, eres libre de modificarlo a tus necesidades.
<x-app-layout>
<x-slot name="header">
<x-auth-validation-errors />
</x-slot>
</x-app-layout>
Creando nuestro propio Middleware
El Middleware que viene con Laravel Ban para detectar si el usuario está baneado tiene el siguiente contenido.
<?php
/*
* This file is part of Laravel Ban.
*
* (c) Anton Komarev <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Cog\Laravel\Ban\Http\Middleware;
use Closure;
use Cog\Contracts\Ban\Bannable as BannableContract;
use Illuminate\Contracts\Auth\Guard;
class ForbidBannedUser
{
/**
* The Guard implementation.
*
* @var \Illuminate\Contracts\Auth\Guard
*/
protected $auth;
/**
* @param \Illuminate\Contracts\Auth\Guard $auth
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
* @throws \Exception
*/
public function handle($request, Closure $next)
{
$user = $this->auth->user();
if ($user && $user instanceof BannableContract && $user->isBanned()) {
$redirectUrl = config('ban.redirect_url', null);
$errors = [
'login' => 'This account is blocked.',
];
$responseCode = $request->header('X-Inertia') ? 303 : 302;
if ($redirectUrl === null) {
return redirect()->back($responseCode)->withInput()->withErrors($errors);
} else {
return redirect($redirectUrl, $responseCode)->withInput()->withErrors($errors);
}
}
return $next($request);
}
}Crea el tuyo personalizado o tenlo en cuenta para lo que necesites.
Unban usuarios
Para eliminar un baneo lo único que debemos hacer es utilizar el método unban de la siguiente forma.
<?php
Route::get("/unban-user", function () {
$user = User::first();
return tap($user)->unban();
});Para conocer todas las características de este package no te pierdas su repositorio.
Curso Laravel 12
Completo 2026
El único curso 100% actualizado que incluye Laravel 12, Livewire 3, Vue 3, React 19 e Inertia 2. Aprende con proyectos reales y las últimas funcionalidades.
star Incluido en cualquier suscripción