Laravel 5.5多身份验证路由问题

3
尝试使用 Doctrine 而非 Eloquent 来实现 Laravel 多重身份验证。我尝试了多种方法,但仍然卡在某个地方。我目前定义了两个保护器、两个模型、两个登录控制器等等。如果我启用其中一个,那么它能够工作。如果我同时尝试两者,只有默认的保护器似乎能够工作。当我尝试访问其他保护器时,我会被重定向到错误的登录页面。
如果我进入 /login - 正常工作
如果我进入 /home (未登录)- 正确重定向到 /login
如果我进入 /register - 正常工作
如果我进入 /admin/login - 正常工作
如果我进入 /admin/register - 正常工作
如果我进入 /admin (未登录)- 失败 - 应该被重定向到 /admin/login,但实际上被重定向到 /login
我相信我漏掉了一些简单的东西。所有东西都可以单独工作。只是让 /admin 路由使用正确的中间件...我想...也许?
我的路由文件:
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');

我尝试了各种路由定义,但这是最新的迭代。以前的迭代也都不起作用。
我的授权文件:
'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,
    ],
],

我的 LoginController(基本上与开箱即用的控制器相同):

class LoginController extends Controller {
  use AuthenticatesUsers;

  protected $redirectTo = '/home';

  public function __construct() {
    $this->middleware('guest')->except('logout');
  }
}

我的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' );
  }
}

我的AdminController:

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

  public function index() {
    return view( 'staff' );
  }
}

我的 RedirectIfStaffUnauthenticated 中间件(已在 Http\Kernel.php 路由中间件注册为 '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 );
  }
}

更新:

更改了web.php中的路由如下(从admin/login和admin/register路由中移除了中间件):

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');

没有变化,仍然无法正常工作。

尝试更改路由如下(将所有管理员路由放入 'staff' 中间件中): 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');

一样的问题,还是没有解决。

1个回答

3

将您的StaffLoginController更改为以下内容:

    <?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' ] );
    }
  }
}

从AdminController中移除构造函数,我们稍后将在路由上调用此中间件。

class AdminController extends Controller {

  public function index() {
    return view( 'staff' );
  }
}

由于您已经将第二个中间件定义为验证admin路由的身份验证中间件,因此不需要将守卫值传递给auth中间件。

请将您的staff中间件更新为以下内容。

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 );
  }
}

现在更新您的路由。
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' );
});

同时在app\Exceptions文件夹下的Handler.php文件中的unauthenticated函数中添加以下代码:

$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'));

请检查您的app/Kernel.php文件,您可以看到guestapp/Http/Middleware/RedirectIfAuthenticated.php中间件的别名。
您不需要在web.php文件和控制器构造函数上都调用构造函数。
这里的RedirectIfStaffUnauthenticated中间件检查根路径/admin是否经过身份验证,并且它具有staff的守卫值,如果没有,它将重定向到/admin/login路由。
请阅读Laravel文档以获得更多澄清信息。
希望这能帮助到您。

尝试从控制器中删除它。我仍然被重定向到/login而不是/admin/login。 - swp
我也尝试将该行更改为$this->middleware('staff'),但效果相同。 我仍然停留在/登录页面。 - swp
你的员工注册和登录路由仍然使用Web中间件,请尝试在web.php文件中将它们与Web中间件分离。 - HasilT
尝试过了。用了几种不同的方式(我在原帖中更新了我尝试的内容)。仍然没有成功。 - swp
我已经编辑了我的回答,如果你遇到任何问题,请告诉我。 - HasilT
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接