1

I would like to implement native multi authentication in my application for two types of users: User and Admin.

  1. I started implementing a new admins table migration (by copying the existing create_users_table).

  2. I created a new model called Admin (by copying the existing User model)

  3. Both (User and Admin) models were updated to specify which guards they use like this:

User Model

protected $guarded  = ['user'];

Admin Model

protected $guarded  = ['admin'];
  1. Then I setup the auth configuration like this:

config/auth.php

https://pastebin.com/iLAZbX2z

  1. Then I defined my custom auth routes for users and admins like this:

routes/web.php

https://pastebin.com/raw/CKX9Xddb

  1. Finally, I defined the auth protected routes for the two user types like this:

routes/web.php

// User auth protected pages
Route::prefix('manage')->middleware('auth:user')->namespace('Manage')->group(function() {

    Route::get('/', 'DashboardController@index');

});

// Admin auth protected pages
Route::prefix('admin')->middleware('auth:admin')->namespace('Admin')->group(function() {

    Route::get('/', 'DashboardController@index');

});

I tested the user login first before proceeding (there's more to be done to get admin to login), by going into http://myapp.local/login and entering my credentials and I was successfully redirected to user's dashboard (i.e. http://myapp.local/manage). All of the user specific functionality (e.g. reset pass) etc.. are all working fine).

However; when testing the guest middleware by visiting http://myapp.local/manage directly, I expected to be redirected to http://myapp.local/login but got an error instead:

Route [login] not defined.

This error is valid; because in the routes definition, I've named the user login as user.login

It looks like the guest middleware uses a hard coded named route called login in the unauthenticated exception handler.

vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php

protected function unauthenticated($request, AuthenticationException $exception)
{
    return $request->expectsJson()
                ? response()->json(['message' => $exception->getMessage()], 401)
                : redirect()->guest(route('login')); // <------
} 

How can I tell the guest middleware to use a differently named route for the login (when un-authenticated user tries to visit a auth protected page)?

I will need to use this later for the admin guest middleware also.

Latheesan
  • 23,247
  • 32
  • 107
  • 201

3 Answers3

1

Thanks to Sohel0415's answer; I realised that the App\Exceptions\Handler extends the vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php, which means I can solve it like this:

I've edited the app\Exceptions\Handler.php like this:

  1. Included this use statement at the top:

use Illuminate\Auth\AuthenticationException;

  1. Added this method:

https://pastebin.com/raw/10Y1tS6d

Latheesan
  • 23,247
  • 32
  • 107
  • 201
0

I've named the user login as user.login

You're getting the error because the route name is user.login and you're trying to use login route. So, use proper route name here:

redirect()->guest(route('user.login')); 
Alexey Mezenin
  • 158,981
  • 26
  • 290
  • 279
  • I am not trying to use the `redirect()->guest(route('login'));` - that's what the framework comes with, the line i posted above was taken from: `vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php` hence why i said the named route is hard coded and I am trying to find a way to override it. – Latheesan Feb 11 '18 at 11:35
0

Use Request::is() to check the requested url, then redirect :

protected function unauthenticated($request, AuthenticationException $exception)
{
      if(\Request::is('manage/*')){
      return $request->expectsJson()
            ? response()->json(['message' => $exception->getMessage()], 401)
            : redirect()->guest(route('user.login'));
      }
      else if(\Request::is('admin/*')){
        return $request->expectsJson()
            ? response()->json(['message' => $exception->getMessage()], 401)
            : redirect()->guest(route('admin.login'));
      }
      else{
        return $request->expectsJson()
            ? response()->json(['message' => $exception->getMessage()], 401)
            : redirect()->guest(route('login'));
      }
}

Note: add this method in App\Exceptions\Handler

Sohel0415
  • 9,523
  • 21
  • 30