Laravel Ban, Suspend or Block and Unban Auth User

Published on Jan 14, 2021

Hi artisans, sometimes we need to ban users from our application. It’s an important feature. Laravel auth provides many functionalities. Unfortunately, they don’t provide the ban/unban option. In this article, I’m going to create the ban & unban feature. I’m testing on Laravel 8.22.1.

Table of Contents

  1. Add Column to User Table
  2. Create a Middleware
  3. Update Login Balde File
  4. Ban a User
  5. Check Banned Status
  6. Unban a User
  7. Outputs

Add Column to User Table

At first, we need to add a column to users table called banned_till. Run this command to create a migration file to create the new column:

php artisan make:migration add_banned_till_to_users_table

Then open the migration file from database/migrations and update up() method like this:

timestamp_add_banned_till_to_users_table.php
class AddBannedTillToUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('banned_till')->nullable();
        });
    }

    // --- REST CODE
}

Then open User model from app/Models dreictory and update $fillable array like:

User.php
protected $fillable = [
    'name',
    'email',
    'password',
    'banned_till'
];

Now migrate the migrations:

php artisan migrate:fresh

Create a Middleware

We need a middleware to check auth user is banned or not. Run this command to create middleware:

php artisan make:middleware IsUserBanned

Open IsUserBanned middleware from app/Http/Middleware path. Then paste this code:

IsUserBanned .php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Str;
use Illuminate\Http\Request;

class IsUserBanned
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (auth()->check() && auth()->user()->banned_till != null) {

            if (auth()->user()->banned_till == 0) {
                $message = 'Your account has been banned permanently.';
            }
            if (now()->lessThan(auth()->user()->banned_till)) {
                $banned_days = now()->diffInDays(auth()->user()->banned_till) + 1;
                $message = 'Your account has been suspended for ' . $banned_days . ' ' . Str::plural('day', $banned_days);
            }

            auth()->logout();
            return redirect()->route('login')->with('message', $message);
        }

        return $next($request);
    }
}

Now let’s register our middleware to app/Http/Kernel.php file. In the Kernel file, there is a group named $middlewareGroups. We have to set our middleware path to the web group like:

Kernel.php
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        // --- MORE
        \App\Http\Middleware\IsUserBanned::class,
    ],

    // --- REST CODE
];

Our middleware is successfully registered.

Update Login Balde File

We have to add a alert div to resources/views/auth/login.blade.php file:

login.blade.php
<!-- ... -->

<div class="card-body">

  @if (session('message'))
    <div class="alert alert-danger">{{ session('message') }}</div>
  @endif

  <form method="POST" action="{{ route('login') }}">
    @csrf
    <!-- ... -->
  </form>

</div>

<!-- ... -->

Ban a User

We’ve completed all the necessary steps. Now let’s ban a user. We need to set timestamp value as the value of banned_till field. Have a look at the example:

use App\Models\User;
use Carbon\Carbon;

public function ban()
{
    // ban for days
    $ban_for_next_7_days = Carbon::now()->addDays(7);
    $ban_for_next_14_days = Carbon::now()->addDays(14);
    $ban_permanently = 0;

    // ban user
    $user_id = 1;
    $user = User::find($user_id);
    $user->banned_till = $ban_for_next_7_days;
    $user->save();
}

If we want to ban a user permanently, we have to set banned_till field’s value to 0 (zero).

Check Banned Status

We can easily check user banned status. Here’s the example:

use App\Models\User;
use Illuminate\Support\Str;

public function bannedStatus()
{
    $user_id = 1;
    $user = User::find($user_id);

    $message = "The user is not banned";
    if ($user->banned_till != null) {
        if ($user->banned_till == 0) {
            $message = "Banned Permanently";
        }

        if (now()->lessThan($user->banned_till)) {
            $banned_days = now()->diffInDays($user->banned_till) + 1;
            $message = "Suspended for " . $banned_days . ' ' . Str::plural('day', $banned_days);
        }
    }

    dd($message);
}

Unban a User

To unban a user, we have to set banned_till value to null.

use App\Models\User;

public function unban()
{
    $user_id = 1;
    $user = User::find($user_id);
    $user->banned_till = null;
    $user->save();
}

Outputs

Have a look at the ouputs. Banned for 7 days:

Banned permanently:

That’s all, artisans. Thanks for reading. ?

Comments (0)