0

I am trying to make Laravel using multiple guards - depending on the authentication type.

When I am authenticating via API, I would like to use jwt guard. When I am authenticating through web, I want to use session guard.

My config\auth.php looks like this:

'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],

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

        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
            //'hash' => false,
        ],
    ],

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

My routes/web.php looks like this:

Route::get('/', 'HomeController@index')->name('home');
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');

My routes/api.php looks like this:

Route::post('login', 'AuthController@login');
Route::get('logout', 'AuthController@logout');
Route::post('refresh', 'AuthController@refresh');
Route::get('me', 'AuthController@me');

What I am getting is that API authentication works fine, while the web doesn't. I have debugged and it seems like it is always checking the jwt guard.

Can someone help me, how can I set the guard on a route if that is possible or on Auth::routes() call?

Bob
  • 8,392
  • 12
  • 55
  • 96
  • you would have to specify the guard to use when dealing with any actions from the 'web' routes ... or you would have to apply the `auth` middleware with the `web` param, `auth:web` so that it will set the default to `web` for the routes protected by that middleware ... most of those controllers for auth have defined middleware in their constructors – lagbox Sep 18 '20 at 21:35
  • @lagbox can you help me out how would you do it? Do you think that I wrap up `routes/web.php` code in `Route::group(['middleware' => ['auth:web']], function () {`? – Bob Sep 18 '20 at 21:41
  • no because everything does not require authentication to be reach and those controllers define their middleware in their constructor ... it would probably be easier for you to leave the default guard as `web` and modify what you need for the "api" side – lagbox Sep 18 '20 at 21:43
  • @lagbox That was my first idea and I tried it like that, but then I was struggling to authenticate using API, since it was always requiring token (even on login urls) – Bob Sep 18 '20 at 21:46
  • because the `auth` middleware is only applied to routes that require an authenticated user; a login route must allow unauthenticated users to reach it otherwise they could not authenticate – lagbox Sep 18 '20 at 21:54
  • @lagbox I have switched now to `web` as default guard. I can login, but I can't authenticate using the API, since I am getting this error: `Method Illuminate\Auth\SessionGuard::factory does not exist.`. It seems like it is using the wrong guard again (trying to use session guard for API authentication) – Bob Sep 18 '20 at 21:59
  • i dont know what you are doing in your routes so i have no idea how you are attempting to authenticate, but any time you are dealing with the `Auth` facade (auth manager) and you want to use the guard that isn't the default you have to tell it which guard to use `Auth::guard(...)->...` – lagbox Sep 18 '20 at 22:00

1 Answers1

0

I have solved it by switching default to web routes.

Then I updated the code for app/Http/Controllers/AuthController.php to use the specific api auth wherever I was using the auth method:

auth('api')->attempt($validator->validated()) and 'expires_in' => auth('api')->factory()->getTTL() * 60

Bob
  • 8,392
  • 12
  • 55
  • 96