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.
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.
来源:https://stackoverflow.com/questions/46270775/laravel-5-5-multi-authentication-routing-issue