最稳妥常用方式是Auth::check(),它只读session/token、不查库不加载模型、返回布尔值;API场景需显式指定guard如Auth::guard('sanctum')->check()。

在 Laravel 9.x 中,中间件判断用户是否登录,最稳妥、最常用的方式是使用 Auth::check(),它不查数据库、不加载用户模型,只读取 session 或 token 状态,返回布尔值,适合做快速守卫。
用 Auth::check() 判断登录态
这是中间件里推荐的写法,轻量且安全:
- 直接调用
Auth::check(),返回true表示已登录,false表示未登录 - 不要在
Auth::check() === false后紧接着调用Auth::user()->name,否则会触发Call to a member function ... on null错误 - 如果需要用户数据,应先确认登录,再调用
Auth::user()或更推荐的auth()->user()(PHP 8.0+ 可配合空合并操作符:auth()->user()?->email)
避免重定向死循环
自定义中间件中若需重定向未登录用户,必须排除登录页、注册页等公共资源路径,否则会因逻辑错误导致无限跳转:
- 错误写法(易引发 ERR_TOO_MANY_REDIRECTS):
!session()->has('userID') && ($request->path() != route('login') || $request->path() != route('register'))
这里用了||,只要一个不等就为真,条件永远成立 - 正确写法:用
in_array()明确放行路径,或用多个&&组合排除if (!Auth::check() && !in_array($request->route()->getName(), ['login', 'register', 'password.request', 'home'])) {<br> return redirect()->route('login');<br>}
区分 guard 场景
Laravel 默认 web guard 适用于 session 登录,但 API 场景下容易误判:
- API 路由默认走
sanctum或passportguard,而Auth::check()默认检查webguard → 总返回false - 如需在 API 中判断,应显式指定 guard:
Auth::guard('sanctum')->check()或auth('sanctum')->check() - 确保路由分组已绑定对应 guard,例如:
Route::middleware('auth:sanctum')
替代方案:用内置 auth 中间件
多数情况下无需手写判断逻辑,Laravel 自带的 auth 中间件已封装完整流程:
- 它自动调用当前 guard 的
authenticate()方法,支持 session/token 验证 - 未登录时跳转由
RedirectIfAuthenticated控制,默认指向route('login') - 只需在路由中加
->middleware('auth'),无需重复造轮子


















