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

guii_amorim's avatar

Multiple Auth guards not working

I'm trying to make multiple auth guards for an api that I'm building. Both guards use the same provider, but uses different models to login. The first one works properly, but the second gives a strange result: if I print the userModel of the provider, it prints the SistemaIntegrado class and the Consultor class, as if there's two requests being made.

AuthServiceProvider

<?php

namespace App\Providers;

use App\Models\Sapv\Consultor;
use App\Models\SistemaIntegrado;
use App\Services\Auth\JWT\JWTGuard;
use App\Services\Auth\JWT\JWTProvider;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        // 'App\Models\Model' => 'App\Policies\ModelPolicy',
    ];

    public function register()
    {
        Auth::provider('integracao', function ($app, array $config) {
            return new JWTProvider($app->make(SistemaIntegrado::class));
        });
        Auth::extend('integracao', function ($app, $name, array $config) {
            return new JWTGuard(Auth::createUserProvider($config['provider']), $app->make('request'));
        });

        Auth::provider('sapvconsultor', function ($app, array $config) {
            return new JWTProvider($app->make(Consultor::class));
        });
        Auth::extend('sapvconsultor', function ($app, $name, array $config) {
            return new JWTGuard(Auth::createUserProvider($config['provider']), $app->make('request'));
        });
    }

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
    }
}

auth.php

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => 'integracao',
//        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'integracao' => [
            'driver' => 'integracao',
            'provider' => 'integracao',
        ],
        'sapvconsultor' => [
            'driver' => 'sapvconsultor',
            'provider' => 'sapvconsultor',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        'integracao' => [
             'driver' => 'integracao',
             'model' => \App\Models\SistemaIntegrado::class,
//             'table' => 'users',
        ],
        'sapvconsultor' => [
            'driver' => 'sapvconsultor',
            'model' => \App\Models\Sapv\Consultor::class,
//             'table' => 'users',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Password Confirmation Timeout
    |--------------------------------------------------------------------------
    |
    | Here you may define the amount of seconds before a password confirmation
    | times out and the user is prompted to re-enter their password via the
    | confirmation screen. By default, the timeout lasts for three hours.
    |
    */

    'password_timeout' => 10800,

];

routes/api.php

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::permanentRedirect('/', '/v1');
Route::any('/v1', fn() => ['api_version' => '1.0.1']);

Route::prefix('v1')->group(function () {
    Route::middleware(['auth:integracao', 'sapv.connection'])->group(function () {
        Route::prefix('integracao')->group(function () {
            Route::prefix('associado')->group(function () {
                Route::get('/', [\App\Http\Controllers\Integracao\Sapv\AssociadoController::class, 'show']);
                Route::get('boleto', [\App\Http\Controllers\Integracao\Sapv\AssociadoController::class, 'boleto']);
            });
        });
    });

    Route::middleware(['sapv.connection', 'auth:sapvconsultor'])->group(function () {
        Route::prefix('sapvconsultor')->group(function () {
            Route::post('login', [\App\Http\Controllers\Sapv\ConsultorController::class, 'login']);
        });
    });
});

In my JWTProvider, this is my retrieveByCredentials functions

public function retrieveByCredentials(array $credentials): ?Model
    {
        try {
            $token = JWTParser::parseToken($credentials['token']);
            $user = $this->userModel->newQuery()->find($token->claims->get('sub'));
            var_dump($this->userModel::class);
            
            return $user;
        } catch (\Exception $e) {
            return null;
        }
    }

When I try to reach the route /v1/sapvconsultor/login i get this output

string(27) "App\Models\SistemaIntegrado"
string(25) "App\Models\Sapv\Consultor"
{"message":"Unauthenticated."}

If I goto the route /v1/integracao/associado/boleto this is the output

string(27) "App\Models\SistemaIntegrado"

I don't know what I am doing wrong, please, can someone advice?

0 likes
2 replies
AlexElementarteilchen's avatar

Hi,

I think there is an error in your auth.php configuration.

When you define the providers -> in the comment above it says | Supported: "database", "eloquent" so I believe you must have

        'integracao' => [
             'driver' => 'eloquent', // not 'integracao',
             'model' => \App\Models\SistemaIntegrado::class,
        ],

Not sure if this solves the problem but worth a try. Hope this helps!

guii_amorim's avatar

@AlexElementarteilchen Hi, thanks for the help but it doesn't work. If I put 'eloquent' in the auth.php file the request doesn't pass through my custom provider, thus not authenticating the user. In fact, the 'integracao' guard does work as it is right now, but the 'sapvconsultor' guard doesn't and I don't understand why, they are the same thing, just with different models attached to the provider.

Please or to participate in this conversation.