【问题标题】:Laravel 5.5 Multi Authentication Routing IssueLaravel 5.5 多认证路由问题
【发布时间】:2018-02-26 11:42:40
【问题描述】:

尝试使用 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' );
  }
}

我的管理员控制器:

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

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

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

更新:

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

同样如此。还是不行。

【问题讨论】:

    标签: php laravel authentication laravel-5 routing


    【解决方案1】:

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

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

    像这样更新你的员工中间件。

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

    还将以下行添加到Handler.php 文件app\Exceptions 中的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 doc 了解详情

    希望这会有所帮助。

    【讨论】:

    • 尝试从控制器中删除它。我最终还是被重定向到 /login 而不是 /admin/login。
    • 我也尝试将该行更改为 $this->middleware( 'staff' ) 但效果相同。我仍然在 /login
    • 您的员工注册和登录路由仍然使用web中间件,尝试在web.php文件中将它们与web中间件分开
    • 试过了。几种不同的方式(我用我尝试过的方式更新了原始帖子)。还是没有运气。
    • 我已经编辑了我的答案,如果您遇到任何问题,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 2018-08-05
    • 2015-07-31
    • 2018-06-23
    • 2019-04-02
    • 2016-06-24
    • 2018-03-01
    相关资源
    最近更新 更多