Laravel Ban, Suspend or Block and Unban Auth User

avatar
Jan 14, 2021 · Article · 5 min, 1055 words

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

No comments yet…