Save the Laravel tymon / jwt-auth blacklist in the database

 The JWT authentication package for Laravel / Lumen, tymon / jwt-auth, saves old tokens that have been logged out or refreshed in the form of a blacklist instead of holding a valid token issued. By default, it is saved in the cache, so you can not scale out unless you share it with Redis etc. So, let's save it in the database.

[1]. Environment

[2]. Create table jwt_auth_storage 
        Define and migrate under database / migrations.

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateJwtAuthStorageTable extends Migration
{
    public function up(): void
    {
        Schema::create('jwt_auth_storage',  
        function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
            $table->timestamp('expires_at')->nullable();
            $table->string('key')->index();
            $table->string('value');
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('jwt_auth_storage');
    }
}

[3]. Create Eloquent Model for jwt_auth_storage table

<?php
namespace App\Model;

use Illuminate\Database\Eloquent\Model;

class JwtAuthStorage extends Model
{
    protected $table = 'jwt_auth_storage';

    protected $fillable = [
        'key', 'value', 'expires_at',
    ];

    protected $dates = ['expires_at'];
}

[4]. Create an access class that inherits Storage
Inherit Tymon \ JWTAuth \ Contracts \ Providers \ Storage and 
create a class that implements each method.
By default, Tymon \ JWTAuth \ Providers \ Storage \ Illuminate :: 
 class is used, so refer to this. 
<?php
namespace App\Repository;

use App\Model\JwtAuthStorage;
use DateTime;
use Tymon\JWTAuth\Contracts\Providers\Storage;

class JwtAuthStorageRepository implements Storage
{
    protected $jwtAuthStorageModel;

  public function __construct(JwtAuthStorage $jwtAuthStorageModel)
    {
        $this->jwtAuthStorageModel = $jwtAuthStorageModel;
    }

    public function add($key, $value, $minutes): void
    {
        $expiresAt = (new DateTime('now'))->modify('+ '  
          . $minutes . ' minutes');
        $this->jwtAuthStorageModel->newQuery()
            ->create([
                'key' => $key,
                'value' => serialize($value),
                'expires_at' => $expiresAt,
            ]);
    }

    public function forever($key, $value): void
    {
        $this->jwtAuthStorageModel->newQuery()
            ->create([
                'key' => $key,
                'value' => serialize($value),
            ]);
    }

    public function get($key)
    {
        $now = new DateTime('now');
        $data = $this->jwtAuthStorageModel->newQuery()
            ->where('key', $key)
            ->where('expires_at', '>', $now)
            ->orderBy('expires_at', 'desc')
            ->first();
        if ($data) {
            return unserialize($data->value);
        } else {
            return null;
        }
    }

    public function destroy($key): bool
    {
        return !!$this->jwtAuthStorageModel->newQuery()
            ->where('key', $key)
            ->delete();
    }

    public function flush()
    {
    }
}

[5]. Publish config file

Extract config / jwt.php into your project to change the settings.

 $ php artisan vendor:publish -- provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"


[6]. Configuration 

 Specify the customized access class in provider.storage in the configuration file (config / jwt.php). Reading and writing the blacklist is done via this class.

 <?php

return [
    ...
    'providers' => [
        ...
      'storage' => App\Repository\JwtAuthStorageRepository::class,
    ], 

]; 







Comments

Popular posts from this blog

Java : Variables Declaring

Install DNF in RHEL/CentOS 7

SQL Self JOIN