3

Trying to get Laravel multiple authentication to work using Doctrine instead of Eloquent. I've tried multiple things but keep getting stuck. I currently have two guards defined, two models, two login controllers, etc. If I enable either one or the other, they work. If I try both at the same time, only the default guard seems to work. When I try to access the other guard, I get redirected to the wrong login page.

If I go to /login - works as expected

If I go to /home (without being logged in) - redirected to /login as expected

If I go to /register- works as expected

If I go to /admin/login - works as expected

If I go to /admin/register - works as expected

If I go to /admin (without being logged in) - fail - should get redirected to /admin/login but instead getting redirected to /login

I'm sure I'm missing something simple. Everything works individually. It's just getting the /admin route to use the right middleware...I think...maybe?

My routes file:

Auth::routes(); // staff authentication routes Route::group( [ 'middleware' => [ 'web' ] ], function() { Route::get( 'admin/login', 'Auth\StaffLoginController@showLoginForm' ); Route::post( 'admin/login', [ 'as' => 'staff.login', 'uses' => 'Auth\StaffLoginController@login' ] ); Route::get( 'admin/register', 'Auth\StaffRegisterController@showRegistrationForm' ); Route::post( 'admin/register', [ 'as' => 'staff.register', 'uses' => 'Auth\StaffRegisterController@register' ] ); Route::group( [ 'middleware' => [ 'staff' ] ], function() { Route::get( '/admin', 'AdminController@index' )->name( 'admin' ); }); }); Route::get('/home', 'HomeController@index')->name('home'); 

I've tried various route definitions but this is the latest iteration. None of the previous iterations worked either.

My auth file:

'defaults' => [ 'guard' => 'web', 'passwords' => 'users', ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], 'staff' => [ 'driver' => 'session', 'provider' => 'adminusers', ] ], 'providers' => [ 'users' => [ 'driver' => 'doctrine', 'model' => App\Users\Customer::class, ], 'adminusers' => [ 'driver' => 'doctrine', 'model' => App\Users\Staff::class, ] ], 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, ], 'adminusers' => [ 'provider' => 'adminusers', 'table' => 'password_resets', 'expire' => 30, ], ], 

My LoginController (basically same as out of the box):

class LoginController extends Controller { use AuthenticatesUsers; protected $redirectTo = '/home'; public function __construct() { $this->middleware('guest')->except('logout'); } } 

My StaffLoginController:

<?php class StaffLoginController extends Controller { use AuthenticatesUsers; protected $redirectTo = '/admin'; protected $guard = 'staff'; public function __construct() { $this->middleware( 'guest' )->except( 'logout' ); } public function showLoginForm() { return view( 'auth.staff.login' ); } public function login( Request $request ) { $this->validate( $request, [ 'email' => 'required|email', 'password' => 'required', ]); if( auth()->guard( 'staff' )->attempt( [ 'email' => $request->input( 'email' ), 'password' => $request->input( 'password' ), ])) { return view( 'staff' ); } else { return view( 'auth.staff.login' )->withErrors( [ 'email' => 'Authentication failed' ] ); } } protected function guard() { return \Auth::guard( 'staff' ); } } 

My AdminController:

class AdminController extends Controller { public function __construct() { $this->middleware( 'auth:staff' ); } public function index() { return view( 'staff' ); } } 

My RedirectIfStaffUnauthenticated middleware (which is registered in Http\Kernel.php routeMiddleware as 'staff' => \SNJ\Http\Middleware\RedirectIfStaffUnauthenticated::class, ):

class RedirectIfStaffUnauthenticated { public function handle( $request, Closure $next, $guard = 'staff' ) { if ( !Auth::guard( $guard )->check() ) { return view( 'auth.staff.login' ); } return $next( $request ); } } 

UPDATE:

Changed routes in web.php to be as thus (removed the middleware from the admin/login and admin/register routes:

Auth::routes(); // staff authentication routes Route::get( 'admin/login', 'Auth\StaffLoginController@showLoginForm' ); Route::post( 'admin/login', [ 'as' => 'staff.login', 'uses' => 'Auth\StaffLoginController@login' ] ); Route::get( 'admin/register', 'Auth\StaffRegisterController@showRegistrationForm' ); Route::post( 'admin/register', [ 'as' => 'staff.register', 'uses' => 'Auth\StaffRegisterController@register' ] ); Route::group( [ 'middleware' => [ 'staff' ] ], function() { Route::get( '/admin', 'AdminController@index' )->name( 'admin' ); }); Route::get('/home', 'HomeController@index')->name('home'); 

No change. Still doesn't work.

Tried changing routes thusly (put all admin routes into 'staff' middleware: Auth::routes();

// staff authentication routes Route::group( [ 'middleware' => [ 'staff' ] ], function() { Route::get( 'admin/login', 'Auth\StaffLoginController@showLoginForm' ); Route::post( 'admin/login', [ 'as' => 'staff.login', 'uses' => 'Auth\StaffLoginController@login' ] ); Route::get( 'admin/register', 'Auth\StaffRegisterController@showRegistrationForm' ); Route::post( 'admin/register', [ 'as' => 'staff.register', 'uses' => 'Auth\StaffRegisterController@register' ] ); Route::get( '/admin', 'AdminController@index' )->name( 'admin' ); }); Route::get('/home', 'HomeController@index')->name('home'); 

Same same. Still doesn't work.

1 Answer 1

3

Change your StaffLoginController to this,

 <?php class StaffLoginController extends Controller { use AuthenticatesUsers; public function showLoginForm() { return view( 'auth.staff.login' ); } public function login( Request $request ) { $this->validate( $request, [ 'email' => 'required|email', 'password' => 'required', ]); if( auth()->guard( 'staff' )->attempt( [ 'email' => $request->input( 'email' ), 'password' => $request->input( 'password' ), ])) { return view( 'staff' ); } else { return view( 'auth.staff.login' )->withErrors( [ 'email' => 'Authentication failed' ] ); } } } 

remove constructor from AdminController, we are later going to call this middleware on routes.

class AdminController extends Controller { public function index() { return view( 'staff' ); } } 

You don't need to pass the guard value to auth middleware since you already defined as second middleware for authenticating admin routes.

update your staff middleware like this.

class RedirectIfStaffUnauthenticated { public function handle( $request, Closure $next, $guard = null ) { if ( Auth::guard( $guard )->check() ) { if(! $guard == 'staff') { return redirect()->route( 'staff.login.form' ); } }else return redirect()->route( 'staff.login.form' ); return $next( $request ); } } 

Now update your routes.

Route::get( 'admin/login', 'Auth\StaffLoginController@showLoginForm' ); Route::post( 'admin/login', [ 'as' => 'staff.login.submit', 'uses' => 'Auth\StaffLoginController@login' ] ); Route::get( 'admin/register', 'Auth\StaffRegisterController@showRegistrationForm' ); Route::post( 'admin/register', [ 'as' => 'staff.register.submit', 'uses' => 'Auth\StaffRegisterController@register' ] ); Route::group( [ 'middleware' => [ 'staff' ] ], function() { Route::get( '/admin', 'AdminController@index' )->name( 'admin' ); }); 

Also add the following lines to your unauthenticated function in Handler.php file in app\Exceptions

$guard = array_get($exception->guards(), 0); switch ($guard) { case 'staff': $login = 'admin/login'; break; case 'users': $login = 'login'; break; default: $login = 'login'; break; } return redirect()->guest(route('login')); 

Please check your app/Kernel.php, you can see that guest is an alias for app/Http/Middleware/RedirectIfAuthenticated.php middleware.

You don't need to call constructors on both web.php file and on the controllers constructor.

Here the RedirectIfStaffUnauthenticated middleware checks the root /admin is authenticated and it has a guard value of staff, if not it will redirect to the /admin/login route.

Please read laravel doc for clarification

Hope this helps.

Sign up to request clarification or add additional context in comments.

7 Comments

Tried removing that from the Controller. I still end up redirected to /login instead of /admin/login.
I also tried changing that line to $this->middleware( 'staff' ) but that had the same effect. I still end up at /login
Your staff register and login routes still use web middleware, try to separate them from web middleware in the web.php file
Tried that. A couple different ways (I updated the original post with what I tried). Still no luck.
I have edited my answer, let me know if you run into any issues.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.