Laravel多认证异常:已登录普通用户仍可访问登录页
Laravel单表多认证:普通用户登录后访问登录页不跳转问题
我在Laravel中通过同一张数据表实现了普通用户(user)和管理员(admin)的多认证功能,目前管理员和普通用户的登录功能均可正常使用,但普通用户登录后,访问登录页路由http://localhost:8000/user/login时仍会显示登录页面,无法自动跳转到http://localhost:8000/user/dashboard;而管理员登录后访问对应登录页则可正常跳转到仪表盘。
相关代码文件:
用户迁移文件:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->integer('is_admin')->default(0); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } }
管理员登录控制器:
<?php namespace App\Http\Controllers\Admin; use Auth; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Foundation\Auth\AuthenticatesUsers; class LoginController extends Controller { use AuthenticatesUsers; // protected $redirectTo = '/admin/dashboard'; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest:admin')->except('logout'); } /** * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function showLoginForm() { return view('admin.pages.login'); } public function login(Request $request) { $this->validate($request, [ 'email' => 'required|email', 'password' => 'required|min:6', 'remember_me'=>'nullable' ]); $request->merge(['user_type'=>'1']); if (Auth::guard('admin')->attempt([ 'email' => $request->email, 'password' => $request->password,'is_admin' => $request->user_type ], $request->input('remember_me'))) { return redirect()->intended(route('admin.dashboard')); } else{ return back()->withErrors(['message'=>'Username or Password is Invalid'])->withInput($request->all()); } //return back()->withInput($request->only('email', 'remember')); } public function logout(Request $request) { Auth::guard('admin')->logout(); $request->session()->invalidate(); return redirect()->route('admin.login'); } }
普通用户登录控制器:
<?php namespace App\Http\Controllers; use Auth; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Foundation\Auth\AuthenticatesUsers; class LoginController extends Controller { use AuthenticatesUsers; // protected $redirectTo = '/user/dashboard'; /** * Create a new controller instance. * * @return void */ public function __construct() { //$this->middleware('guest:web')->except('logout'); // $this->middleware('guest', ['except' => 'logout']); //$this->middleware('guest:web')->except('logout'); } /** * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function showLoginForm() { return view('pages.login'); } public function login(Request $request) { $this->validate($request, [ 'email' => 'required|email', 'password' => 'required|min:6', 'remember_me'=>'nullable' ]); $request->merge(['user_type'=>'0']); if (Auth::guard('web')->attempt([ 'email' => $request->email, 'password' => $request->password,'is_admin' => $request->user_type ], $request->input('remember_me'))) { return redirect()->intended(route('web.dashboard')); } else{ return back()->withErrors(['message'=>'Username or Password is Invalid'])->withInput($request->all()); } //return back()->withInput($request->only('email', 'remember')); } public function logout(Request $request) { Auth::guard('web')->logout(); $request->session()->invalidate(); return redirect()->route('user.login-show'); } public function dashboard() { $this->data['page_js'] = ''; // ['_admin/plugins/raphael/raphael.min.js','_admin/plugins/morrisjs/morris.js']; $this->data['userData'] = Auth::guard('web')->user(); $this->data['title'] = 'User Dashboard'; return view('pages.dashboard', $this->data); } }
路由配置:
Route::get('/admin', 'Admin\LoginController@showLoginForm')->name('admin.login'); Route::get('/login', 'LoginController@showLoginForm')->name('login-show'); Route::group(['prefix' => 'admin'], function () { Route::get('login', 'Admin\LoginController@showLoginForm')->name('admin-login-show'); Route::post('login', 'Admin\LoginController@login')->name('admin.login.post'); Route::group(['middleware' => ['auth:admin', 'prevent-back-history']], function () { Route::get('/dashboard', 'Admin\AdminController@dashboard')->name('admin.dashboard'); }); Route::post('logout', 'Admin\LoginController@logout')->name('admin.logout'); }); Route::group(['prefix' => 'user'], function () { Route::get('login', 'LoginController@showLoginForm')->name('user.login-show'); Route::post('login', 'LoginController@login')->name('login.post'); Route::group(['middleware' => ['auth:web', 'prevent-back-history']], function () { Route::get('/dashboard', 'LoginController@dashboard')->name('web.dashboard'); }); Route::post('logout', 'LoginController@logout')->name('logout'); });
配置文件auth.php:
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', 'hash' => false, ], 'admin' => [ 'driver' => 'session', 'provider' => 'admin', ], ], /* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | If you have multiple user tables or models you may configure multiple | sources which represent each model / table. These sources may then | be assigned to any extra authentication guards you have defined. | | Supported: "database", "eloquent" | */ 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], 'admin' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], // 'users' => [
RedirectIfAuthenticated中间件:
<?php namespace App\Http\Middleware; use App\Providers\RouteServiceProvider; use Closure; use Illuminate\Support\Facades\Auth; class RedirectIfAuthenticated { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string|null $guard * @return mixed */ public function handle($request, Closure $next, $guard = null) { switch ($guard) { case 'admin': if (Auth::guard($guard)->check()) { return redirect()->route('admin.dashboard'); } case 'web': if (Auth::guard($guard)->check()) { return redirect()->route('web.dashboard'); } default: if (Auth::guard($guard)->check()) { return redirect('/'); } break; } return $next($request); } }
Authenticate中间件:
<?php namespace App\Http\Middleware; use Illuminate\Auth\Middleware\Authenticate as Middleware; use Route; class Authenticate extends Middleware { /** * Get the path the user should be redirected to when they are not authenticated. * * @param \Illuminate\Http\Request $request * @return string|null */ protected function redirectTo($request) { if (! $request->expectsJson()) { if(Route::is('admin.*')){ return route('admin-login-show'); } return route('user.login-show'); } } }
解决方案
1. 恢复普通用户登录控制器的中间件设置
问题核心是普通用户的LoginController中注释掉了guest:web中间件,导致登录后访问登录页时不会触发跳转逻辑。打开App\Http\Controllers\LoginController,修改__construct方法:
public function __construct() { $this->middleware('guest:web')->except('logout'); }
这个中间件的作用是:当用户已通过web guard认证时,访问登录页就会触发RedirectIfAuthenticated中间件,自动跳转到用户仪表盘。管理员的控制器已经配置了guest:admin中间件,所以能正常跳转,普通用户只需补上这个配置即可。
2. 优化RedirectIfAuthenticated中间件的switch逻辑(可选但推荐)
当前的switch语句中,case 'admin'后没有添加break,会继续执行后续case的代码,虽然当前管理员的场景能正常工作,但存在潜在逻辑问题。建议给每个case添加break:
public function handle($request, Closure $next, $guard = null) { switch ($guard) { case 'admin': if (Auth::guard($guard)->check()) { return redirect()->route('admin.dashboard'); } break; case 'web': if (Auth::guard($guard)->check()) { return redirect()->route('web.dashboard'); } break; default: if (Auth::guard($guard)->check()) { return redirect('/'); } break; } return $next($request); }
内容的提问来源于stack exchange,提问作者user3653474
相关产品推荐
相关产品推荐

