Auth::check() 和 Auth::guest() 应在认证服务启动后使用,前者判断是否登录并返回布尔值,后者语义化替代 !Auth::check();调用前须确保已执行 Auth::login($user) 或经过 auth 中间件,避免空值错误。

Auth::check() 和 Auth::guest() 怎么用才不踩空值错误
直接调用 Auth::check() 前,必须确保 Laravel 的认证服务已启动——它依赖 auth 中间件或已执行过 Auth::login($user)。常见错误是未登录就访问 Auth::user(),返回 null,接着调用 Auth::user()->name 就抛出 Call to a member function name() on null。
正确姿势是先用 Auth::check() 判断,再取用户;或用 Auth::guest() 替代 !Auth::check(),语义更清晰:
if (Auth::check()) {
echo '欢迎,' . Auth::user()->name;
} else {
echo '请先登录';
}
-
Auth::check()返回布尔值,不抛异常,适合所有上下文(包括 Blade 模板、控制器、命令行) -
Auth::user()在未登录时返回null,不是异常,别指望它自动跳转或提示 - 在中间件里用
Auth::guard('api')->check()时,注意 guard 名必须存在且已配置,否则静默失败
Auth::attempt() 失败却不报错?排查这三点
Auth::attempt() 默认只校验 email 和 password 字段,且要求数据库中 password 是 bcrypt 加密的哈希值。失败时它只返回 false,不抛异常,也不说明原因,容易误判为“密码错了”,实际可能是字段名、状态字段或验证逻辑问题。
- 确认模型的
$fillable或$guarded允许email字段被查询(默认没问题),但如果你改了登录字段(比如用username),得传数组:Auth::attempt(['username' => $input, 'password' => $pwd]) - 检查用户模型是否启用了软删除(
SoftDeletestrait),若用户已被软删,attempt()会静默失败——需在authenticate方法里手动加->withTrashed()或重写retrieveByCredentials() - 如果加了额外验证(如
status = 1),不能靠attempt()自动处理,得自己查:User::where('email', $email)->where('status', 1)->first(),再比对密码
Auth::login() 后为什么没写入 session?
Auth::login($user) 本身不触发 session 写入,它只是把用户实例绑定到当前 guard;session 实际在响应结束前由框架自动保存。但如果在命令行(Artisan 命令)、API 路由(无 session 中间件)或 phpunit 测试中调用,session 根本不可用,Auth::login() 就成了“假登录”——后续请求依然未认证。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
立即学习“PHP免费学习笔记(深入)”;
- Web 路由必须经过
web中间件组(含StartSession),否则Auth::login()无效 - API 场景下,别用
Auth::login(),应改用 token(如 Sanctum 的$user->createToken()) - 测试时用
$this->actingAs($user),而不是手动Auth::login($user),后者在测试环境 session 不生效 - 调用后立刻
dd(Auth::check())可能还是false,因为 session 尚未 commit;用Auth::id()或Auth::user()更可靠
自定义 guard 时 Auth::user() 总是 null
声明新 guard(比如 admin)后,Auth::user() 默认仍走 web guard,不会自动切换。必须显式指定 guard 才能获取对应用户:Auth::guard('admin')->user()。
- 配置文件
config/auth.php中的defaults.guard只影响Auth::未指定 guard 时的默认行为,不影响已命名的 guard 调用 -
Auth::shouldUse('admin')可临时切换默认 guard,但仅限当前请求生命周期,不推荐用于复杂逻辑 - Blade 中不能写
@auth('admin')—— 这是语法错误;正确写法是@if (Auth::guard('admin')->check()) - 路由中间件要用
auth:admin,不是auth:guard=admin,冒号后直接跟 guard 名
Guard 切换和 session 生命周期的耦合最容易被忽略:一个请求里混用多个 guard 时,Auth::user() 和 Auth::guard('x')->user() 返回的可能是完全不同的用户实例,甚至来自不同数据库连接。别假设它们共享状态。


















