Multi-Table Authentication with Laravel and JWT

Table of Contents

  • Level 1: Install Laravel and Setup Basic User Tables
  • Level 2: Install Laravel JWT Package
  • Level 3: Staff Authentication

Its been one of the common use case scenario to authenticate users from different types. Imagine you are creating an app the requires two tables for users and staffs. With Laravel, you can define multiple authentication provider and will solve your problem in a matter of minutes.

Let me show you how.

Level 1: Install Laravel and Setup Basic User Tables

First we need to install Laravel. You can find my current dev environment here: How to Install Laravel Valet and Setup a new server

> laravel new multi-auth
> cd multi-auth

Next, let’s set up database connection and environment configuration. By default Laravel will create this for you. Just verify that you are using the correct database configuration so you can connect to your mysql datasource. If you are using the default mysql username your env file should be like this

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=multi_auth_db
DB_USERNAME=root
DB_PASSWORD=

Take note that we changed the database name to multi_auth_db Now we need to make sure that users and staff tables are existing. When installing Laravel, it automatically creates a migration file for users so we only need to setup staffs migration file. We can easily see create this using the Laravel artisan command:

> php artisan make:migration create_staff_table

Update the migration staff table migration file by opening create_staff_table.php in database/migrations. Inside the up function, type the lines below to build the table columns.

Schema::create('staff', function (Blueprint $table) {
    $table->id();
    $table->string("first_name");
    $table->string("last_name");
    $table->string("email");
    $table->string("password");
    $table->timestamps();
});

Now run the command below back in your terminal to migrate the tables in your database.

> php artisan migrate

Level 2: Install Laravel JWT Package

For our JSON Web Token Management, we will install a library from tymon

https://jwt-auth.readthedocs.io/en/develop/laravel-installation/
> composer require tymon/jwt-auth
> php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
> php artisan jwt:secret

Basically the commands above do the following setup:

  • Install the package using composer,
  • Publish the configuration file which is located in your config/jwt.php
  • Generate a secret token. This secret token will be added to your .env file.

Open your .env file and see the following line. Of course, your key will be different from this one.

JWT_SECRET=...CglEto...qCZaofU9sYxCy9i2ztFJcf3L...

User Configuration

Update your User model to implement the JWTSubject contract. This make sure that your user model have the getJWTIdentifier() which return a unique key from the user instance and getJWTCustomClaims() for defining custom claims.

<?php

namespace App;

...

use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
     ...

    /**
     * @inheritDoc
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * @inheritDoc
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

Make sure that you do the same to the Staff model.

We need to tell Laravel to have two guards, one is for normal user and another one for the staff. Both of this guards will use jwt as the driver but the provider will be coming from two different tables. To do this, let’s update auth.php


    ...
    
    'defaults' => [
            'guard' => 'api', // set the default guard to 'api'
            'passwords' => 'users',
        ],
    
    'guards' => [
            'web' => [
                'driver' => 'session',
                'provider' => 'users',
            ],
    
            'api' => [
                'driver' => 'jwt', // set to jwt token
                'provider' => 'users',
                'hash' => false,
            ],
    
            'staff-api' => [ // add another guard for the staff
                'driver' => 'jwt',
                'provider' => 'staff', // set the provider
                'hash' => false,
            ],
      ],
    'providers' => [
            'users' => [
                'driver' => 'eloquent',
                'model' => App\User::class,
            ],
            'staff' => [ // Add new staff provider
                'driver' => 'eloquent',
                'model' => App\Staff::class,
            ],
    
    ]
    
    ...

Leave a Reply

Your email address will not be published. Required fields are marked *