auth::user() 返回 NULL 主因是用户未登录或中间件配置错误;需检查是否启用 auth 中间件、api 路由的 guard 类型是否匹配、Token 是否有效、blade 中是否判空,队列中须传 id 而非用户对象。

Auth::user() 返回 null 怎么办
多数时候不是代码写错了,而是用户根本没登录,或者中间件没加对。Auth::user() 只在已认证会话中返回 User 实例,否则直接返回 null,不抛异常。
- 检查路由是否用了
auth中间件,比如Route::get('/profile', [ProfileController::class, 'show'])->middleware('auth'); - 如果是 API 路由,
auth:api和auth:sanctum不能混用,Token 过期或 header 缺失Authorization: Bearer xxx都会导致Auth::user()为null - Blade 模板里别直接调用
Auth::user()->name,先判空:@if(auth()->check()) {{ auth()->user()->name }} @endif
Auth::user() 和 auth()->user() 有啥区别
没区别,完全是同一个东西。前者是门面(Facade),后者是辅助函数,底层都走 AuthManager 的 guard() 实例。
-
Auth::user()依赖Auth门面注册,如果手动删过config/app.php里的Auth别名,就会报错Class 'Auth' not found -
auth()->user()更轻量,不依赖门面,适合在 Service 类、console 命令或测试中快速取用户 - 两者默认都操作
webguard,想切到其他 guard(比如admin)得显式指定:auth('admin')->user()
Auth::user() 在队列任务里拿不到用户
队列任务是异步执行的,和原始 http 请求完全隔离,Auth::user() 在里面永远是 null —— 因为 session 和认证上下文根本没传进去。
- 必须在分发任务前把用户 ID 存下来,比如:
ProcessOrder::dispatch($order, auth()->id()); - 不要序列化整个 User 对象传进任务,容易因模型关系或访问器触发意外查询或报错
- 在任务里用
User::find($userId)或User::findOrFail($userId)重新查,确保数据最新
Auth::user() 的性能和缓存行为
它本身不查库,只是从当前 guard 的 session 或 token 解析出用户 ID,再从缓存(如 redis)或数据库里拉一次用户记录,默认走 Eloquent 的 find(),不带任何 eager load。
- 频繁调用
Auth::user()不会造成 N+1,但每次都会触发一次模型实例化,如果只用其中一两个字段,不如提前存变量:$user = auth()->user(); echo $user->email; - 如果开启了
remember_token且用户在别处登出,下次调用可能抛TokenMismatchException,这不是Auth::user()的问题,而是 guard 的验证逻辑在起作用 - 自定义 User 模型里重写了
getAuthIdentifierName()却忘了同步改数据库字段,也会导致Auth::user()查不到人
最常被忽略的是 guard 切换场景:你在 config/auth.php 里配了多个 guard,但没意识到 Auth::user() 默认只认 web,连 auth:api 中间件下跑的控制器里它也是空的——除非你主动切过去。