Laravel 10控制器中实现Auth中间件如何避免无限重定向?
Laravel 10 auth中间件引发无限重定向循环的问题排查与解决
问题场景
在UserController的构造方法中添加了auth中间件:
public function __construct() { $this->middleware('auth'); }
路由配置如下:
Route::get('/', function () { return view('welcome'); }); Route::get('home', [UserController::class,'home'])->name('home'); Route::get('login', [UserController::class, 'showLoginForm'])->name('login'); Route::post('login', [UserController::class, 'login'])->name('login'); Route::get('logout', [UserController::class, 'logout'])->name('logout');
期望访问/home时跳转到登录页,登录成功后进入home页面,但实际出现了无限重定向循环。尝试使用$this->middleware('auth')->except(['login']);后问题依旧。
错误原因
你使用except(['login'])只排除了POST登录请求对应的login方法,但GET登录页面对应的showLoginForm方法并没有被排除在auth中间件之外。
当未登录用户访问/home时,auth中间件会将用户重定向到login路由(即/login),但此时访问/login会触发UserController的showLoginForm方法,而这个方法依然受auth中间件保护,中间件会再次要求用户登录,重定向到login路由,由此形成无限循环。
解决方法
方法1:修正中间件排除的方法列表
需要把showLoginForm和login两个方法都排除在外,确保登录相关的页面和接口都能被未登录用户访问:
public function __construct() { $this->middleware('auth')->except(['showLoginForm', 'login', 'logout']); }
额外加上
logout是为了避免已登出用户访问/logout时被重定向,可根据实际需求调整。
方法2:拆分控制器(更规范的做法)
Laravel默认的认证逻辑通常会把登录、注册等操作放在单独的控制器中,UserController只处理需要认证后的用户操作,这样能避免中间件配置冲突,代码结构更清晰:
- 创建
AuthController,将showLoginForm、login、logout方法移到该控制器中,该控制器无需添加auth中间件。 UserController保留auth中间件,只处理home等需要认证的方法。- 调整路由:
Route::get('/', function () { return view('welcome'); }); // 认证相关路由 Route::get('login', [AuthController::class, 'showLoginForm'])->name('login'); Route::post('login', [AuthController::class, 'login'])->name('login'); Route::get('logout', [AuthController::class, 'logout'])->name('logout'); // 需要认证的路由 Route::middleware('auth')->group(function () { Route::get('home', [UserController::class,'home'])->name('home'); });
内容的提问来源于stack exchange,提问作者Juan
相关产品推荐
相关产品推荐

