Laravel 5.5 多重认证路由问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46270775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 16:40:10  来源:igfitidea点击:

Laravel 5.5 Multi Authentication Routing Issue

phplaravelauthenticationlaravel-5routing

提问by swp

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.

尝试使用 Doctrine 而不是 Eloquent 使 Laravel 多重身份验证工作。我尝试了多种方法,但一直卡住。我目前定义了两个守卫、两个模型、两个登录控制器等。如果我启用其中一个,它们就可以工作。如果我同时尝试两者,似乎只有默认的守卫有效。当我尝试访问另一个守卫时,我被重定向到错误的登录页面。

If I go to /login - works as expected

如果我去 /login - 按预期工作

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

如果我去 /home(没有登录) - 按预期重定向到 /login

If I go to /register- works as expected

如果我去 /register- 按预期工作

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

如果我去 /admin/login - 按预期工作

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

如果我去 /admin/register - 按预期工作

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

如果我去 /admin(没有登录) - 失败 - 应该被重定向到 /admin/login 而是被重定向到 /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?

我确定我错过了一些简单的东西。一切都单独工作。它只是让 /admin 路由使用正确的中间件......我想......也许吧?

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):

我的 LoginController(与开箱即用基本相同):

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:

我的 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, ):

我的 RedirectIfStaffUnauthenticated 中间件(在 Http\Kernel.php routeMiddleware 中注册为 '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:

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

No change. Still doesn't work.

没变。还是不行。

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

尝试更改路由(将所有管理路由放入“员工”中间件: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.

彼此彼此。还是不行。

采纳答案by HasilT

Change your StaffLoginControllerto this,

改变你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' ] );
    }
  }
}

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

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

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 adminroutes.

您不需要将保护值传递给 auth 中间件,因为您已经定义为用于验证admin路由的第二个中间件。

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 unauthenticatedfunction in Handler.phpfile in app\Exceptions

还将以下几行添加到文件中的unauthenticated函数 Handler.phpapp\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 guestis an alias for app/Http/Middleware/RedirectIfAuthenticated.phpmiddleware.

请检查您的app/Kernel.php,您可以看到这guestapp/Http/Middleware/RedirectIfAuthenticated.php中间件的别名。

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

您不需要在web.php文件和控制器构造函数上调用构造函数。

Here the RedirectIfStaffUnauthenticatedmiddleware checks the root /adminis authenticated and it has a guard value of staff, if not it will redirect to the /admin/loginroute.

此处RedirectIfStaffUnauthenticated中间件检查根/admin是否已通过身份验证,并且其保护值为staff,否则将重定向到/admin/login路由。

Please read laravel doc for clarification

请阅读laravel doc以进行澄清

Hope this helps.

希望这可以帮助。