You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 11中Lockout事件监听器未触发问题求助

Laravel账号锁定事件监听器未触发问题解决

我正在开发首个Laravel项目——简易用户管理系统,使用Laravel 11.16.0(Jetstream/Livewire)+ Fortify实现登录功能。系统默认配置为1分钟内5次登录失败触发账号锁定,测试时会返回429 HTTP错误,但自定义的Lockout事件监听器未触发:监听器中的error_log日志未输出,User表的account_locked字段也未被设为true。

需求是:当用户因多次登录失败被锁定时,将User表中对应用户的account_locked(boolean类型,默认false)字段更新为true。

相关代码如下:

EventServiceProvider.php

namespace App\Providers;

use Illuminate\Auth\Events\Lockout;
use App\Listeners\LockoutListener;
use Illuminate\Support\ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        Failed::class => [
            FailedLoginListener::class,
        ],
        Lockout::class => [
            LockoutListener::class,
        ],
        Authenticated::class => [
            SuccessfulLoginListener::class,
        ],
    ];
}

LockoutListener.php

namespace App\Listeners;

use App\Models\User;
use Illuminate\Auth\Events\Lockout;

class LockoutListener
{
    public function handle(Lockout $event): void
    {
        error_log('Lockout event triggered!');
        User::where('email', $event->request->user->email)->update(['account_locked' => true]);
    }
}

问题排查与解决步骤

1. 补全EventServiceProvider的类引入

当前代码中Failed::class和Authenticated::class未引入对应命名空间,会导致事件监听注册失败,补充后代码如下:

namespace App\Providers;

use Illuminate\Auth\Events\Lockout;
use Illuminate\Auth\Events\Failed;
use Illuminate\Auth\Events\Authenticated;
use App\Listeners\LockoutListener;
use App\Listeners\FailedLoginListener;
use App\Listeners\SuccessfulLoginListener;
use Illuminate\Support\ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        Failed::class => [
            FailedLoginListener::class,
        ],
        Lockout::class => [
            LockoutListener::class,
        ],
        Authenticated::class => [
            SuccessfulLoginListener::class,
        ],
    ];
}

2. 修正LockoutListener中的用户查询逻辑

Lockout事件触发时用户尚未完成认证,$event->request->user为null,无法获取邮箱。应直接从请求中取登录提交的email参数:

namespace App\Listeners;

use App\Models\User;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Support\Facades\Log;

class LockoutListener
{
    public function handle(Lockout $event): void
    {
        Log::info('Lockout event triggered for email: ' . $event->request->email);
        User::where('email', $event->request->email)->update(['account_locked' => true]);
    }
}

3. 清除事件缓存

Laravel 11默认开启事件缓存,修改EventServiceProvider后需执行命令清除缓存使配置生效:

php artisan event:clear

后续若需优化性能,可重新生成事件缓存:

php artisan event:cache

4. 确认日志输出位置

error_log的输出位置依赖PHP配置,改用Laravel自带日志系统(Log::info())后,日志会写入storage/logs/laravel.log,便于直接查看事件是否触发。

5. 验证Fortify锁定配置

确认config/fortify.php中已启用登录节流逻辑:

'features' => [
    Features::login(),
    Features::resetPasswords(),
    // 其他功能...
],

Fortify的登录节流由ThrottlesLogins trait实现,满足条件时会自动触发Illuminate\Auth\Events\Lockout事件。


内容的提问来源于stack exchange,提问作者Matheus Caetano Rocha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 07:32:08