Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

dixitchopra's avatar

JWT and Multiple authentication tables

I am using JWT for tokens using this library - https://github.com/tymondesigns/jwt-auth. I have two entities merchants(user) and customers. A merchant can be a customer as well for another merchant so am not putting both in the same user_credentials table. The user authentication works correctly with user_credentials table.

I am looking to authenticate customers as well which are stored on different table named customer_credentials. What I need to do is to use JWT token for customers authentication too.

How can I use JWT for both the tables in Laravel 5?

0 likes
24 replies
davorminchorov's avatar

Ok, so an Web App/API User can have a role of user or merchant (or sometimes both)? This looks like a users and roles tables to me.

If you go your way and create credentials table for every role, you may end up with 10 different tables and it will become chaos for managing.

2 likes
dixitchopra's avatar

I agree to your point. I think, I should add another column of role_type in user_credentials table. Then i'lI assign different payloads based on user role. Am I right?

taijuten's avatar

As @Ruffles has mentioned, it is much better to have a single users table.

If each user can only have one account type, then you could use polymorphism to store different metadata about the account.

However, it sounds like you have a user which can have multiple roles for different merchants. How I've handled this in my projects is combining a pivot table and model.

i.e.

merchant_role_user table

id | merchant_id | role_id | user_id

user model

belongsToMany('App\User', 'merchant_role_model');

hasMany('App\MerchantRoleModel', 'merchant_role_model');

You can then get all of a user's merchants with the belongsToMany, but if you want to get the role, you'd use the pivot table.

1 like
davorminchorov's avatar

users table for the users and roles table for the roles which will have a many to many relationship (role_user pivot table). If you need permissions for every role, you can add a permissions table with a many to many relationship to the roles table.

dixitchopra's avatar

@Ruffles What if both merchant and customer email is same. I won't be able to authenticate both with the role column.

User Table

User_id - 1 | abc@gmail.com | MILLER | 0000000 (office)
User_id - 2 | xyz@gmail.com | JOHN | 2222222 (personal)
User_id - 3 | abc@gmai.com  | MILLER | 11111111 (personal)

Here abc@gmail.com belongs to both merchant and customer. 

User_Credentials table

User_id - 1 | abc@gmail.com | pswd | role - Merchant
User_id - 2 | xyz@gmail.com | pswd | role - Customer
User_id - 3 | abc@gmai.com  | pswd | role - Customer

Here abc@gmail.com belongs to both merchant and customer. I don't know how can I go forward from here.
davorminchorov's avatar

A user with a role of user and merchant will have 1 email, and (s)he'll only be able to access pages where the users with the roles of user and merchant are allowed.

dixitchopra's avatar

Is there any way to use two different tables and use JWT to authenticate.

davorminchorov's avatar

It looks like your users table contains profile details for users and your users_credentials table contains login info.

Why don't you have a users table with the credentials in it, a profiles table with user profile info in it and a roles table with the roles in it?

  • Many users belong to many roles and many roles belong to many users (many to many relationship)
  • A user can have one profile and a profile belongs to one (one to one relationship)

Later on, if you think that 2 different users with the same role should have different access / permissions, you can add a permissions table and set up a many to many relationship with the roles table.

I don't think you need a table for each role. As I said above, it seems like a very complex thing once you start adding more roles to the system.

dixitchopra's avatar

I just have to write JWTAuth::attempt($userCredential)) for logging in to the system and get token. How will system come to know which role to be chosen. Email address is same for both Merchant and User, how can I write where query here (that choose where role = Merchant)

davorminchorov's avatar

Emails should be unique per user. You can't have a user with 2 emails abc@gmail.com for example. Rethink your database structure and improve it.

1 like
geea's avatar

you can define in your middleware \Config::set('jwt.user' , "App\Customers");

it should work.

1 like
nguyenhieptn's avatar

You can easy change the User Model by modify the Config as what I do in my code Config::set('auth.providers.users.model', \App\Customer::class);

        $credentials = $request->only('username', 'password');
        try {
            Config::set('auth.providers.users.model', \App\Customer::class);
            // verify the credentials and create a token for the user
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 401);
            }

        } catch (JWTException $e) {
            // something went wrong

            return response()->json(['error' => 'could_not_create_token'], 500);
        }
nguyenhieptn's avatar

@yigitozkavci Your Auth providers might not been config. remember to config your provider as in code These are my providers: file: config/auth.php

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],

as you can see after

Config::set('auth.providers.users.model', \App\Customer::class);

Our new user provider will be Customer class instead of User class

FaresWardeni's avatar

It worked for me , i have 2 users client and salon_owner , to change i update 2 things auth.model and jwt.user :

Config::set('jwt.user', 'App\Salon_owner'); Config::set('auth.providers.users.model', \App\SalonOwner::class);

AhmedAbdelhedi's avatar

I just implemented jwt-auth to work for my API.

I have two tables and models for users.

One is Admin (table:User) for the backend users and the other is User (table:usermobile), for the application (api) usermobile. The model Admin the default auth and it`s in the config/auth.php.

In config/jwt.php, the user is set to 'App\usermobile', but it`s still related to the Admin model.

What can i do to make for my api to work for the Model usermobile (table:usermobile) ?

fercho9212's avatar

I worked with \Config::set('jwt.user' , "App\Dirver"); \ Config::set('auth.providers.users.model', \App\Dirver::class); but when I log in I get the token from the table driver but that same token lets me log in to the other table as I can avoid that Thanks.

ktscript's avatar

better try to use changing the guard instead of playing with the config. for me on laravel > 8.4 it was more preferable. just write in the Login controller of the corresponding route auth()->shouldUse('admin'); or directly specify the guard, for example response()->json(auth('admin')->user()) when requesting the profile

kanishk_12's avatar

@ktscript I was struck with the same problem. I can't get your idea, can you please explain briefly dude!? Please show me your guards list!

ktscript's avatar

@kanishk_12 my login controller looks like this:

<?php

namespace App\Http\Controllers\Admin\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;

use JWTAuth;
use App\Models\Admin;

use Illuminate\Support\Facades\Hash;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

class LoginAdminController extends Controller
{

    use AuthenticatesUsers;

    protected $redirectTo = RouteServiceProvider::ADMIN_HOME;

    public function __construct()
    {
        $this->middleware('auth.jwt', ['except' => ['login', 'registration']]);
    }

    public function login()
    {

        $credentials = request(['email', 'password']);
        
        try {
            auth()->shouldUse('admin');

            $admin = Admin::where('email', $credentials['email'])->where('pub', 1)->first();
            if ( empty($admin) ) {
                return response()->json(['error' => 'invalid_credentials'], 400);
            }

            if ( ! $token = JWTAuth::attempt($credentials) ){ 
                return response()->json(['error' => 'invalid_credentials'], 400);
            }
        } catch (JWTException $e) {
            return response()->json(['error' => 'could_not_create_token'], 500);
        }

        return $this->respondWithToken($token);
    }

    public function registration()
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:admins',
            'password' => 'required|string|min:6|confirmed',
        ]);

        if ($validator->fails()){
                return response()->json($validator->errors()->toJson(), 400);
        }
		
		auth()->shouldUse('admin');

        $admin = Admin::create([
            'name' => $request->get('name'),
            'email' => $request->get('email'),
            'password' => Hash::make($request->get('password')),
        ]);
		
        $token = JWTAuth::fromUser($admin);

        return $this->respondWithToken($token);
    }

    public function me()
    {
        return response()->json(auth('admin')->user());
    }

    public function logout()
    {
        auth('admin')->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }
}

Please or to participate in this conversation.