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

Laravel事件监听中如何发送未加密的用户密码至邮件

问题场景

管理员创建用户时会自动生成明文密码,哈希后存入数据库,但通过UserCreated事件传递的User模型无法获取明文密码,导致邮件无法发送完整的登录凭证。

现有代码如下:

EventServiceProvider 配置

protected $listen = [
    'App\Events\UserCreated' => [
        'App\Listeners\SendCredentials'
    ],
];

UserCreated 事件

class UserCreated
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $user;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($user)
    {
        $this->user = $user;
    }
}

SendCredentials 监听器

class SendCredentials
{
    /**
     * Handle the event.
     *
     * @param  \App\Events\UserCreated  $event
     * @return void
     */
    public function handle(UserCreated $event)
    {
        $user = $event->user;
        Mail::to($user->email)->send(new SendUserMail($user));
    }
}

触发事件的代码

public function createUser(){
    $this->validate();

    $randomPass = Str::random(8);
    $userCreds = ['email' => $this->email, 'password' => $randomPass];

    try{
        $test = User::firstOrCreate([
            'name' => $this->name,
            'email' => $this->email,
            'password' => Hash::make($randomPass),
            'email_verified_at' => Carbon::now(),
            'user_type' => (int)$this->selectedUser,
            'assigned_to' => (int)$this->selectedAssigned,
            'doctor_type' => $this->selectTypeDoc,
        ]);

        // Mail::to($this->email)->send(new SendUserMail($userCreds));
        UserCreated::dispatch($test);

        $this->reset();
        $this->emitUp('refreshParent');
        $this->dispatchBrowserEvent('swal-insert');

    }catch(\Exception $e){
        $this->dispatchBrowserEvent('createUser-error');
    }

    $this->closeModal();
}

核心问题:如何在邮件中发送未加密的明文密码?


解决方案

方法一:修改事件,同时传递User模型和明文密码

  1. 更新UserCreated事件,新增明文密码属性:
class UserCreated
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $user;
    public $plainPassword; // 新增明文密码属性

    public function __construct($user, $plainPassword)
    {
        $this->user = $user;
        $this->plainPassword = $plainPassword;
    }
}
  1. 触发事件时传入明文密码:
// 替换原触发代码
UserCreated::dispatch($test, $randomPass);
  1. 更新监听器,将明文密码传给邮件:
class SendCredentials
{
    public function handle(UserCreated $event)
    {
        $user = $event->user;
        $plainPassword = $event->plainPassword;
        Mail::to($user->email)->send(new SendUserMail([
            'user' => $user,
            'password' => $plainPassword
        ]));
    }
}

方法二:临时给User模型添加明文密码属性

这种方法不需要修改事件构造参数,在创建用户后给模型临时赋值(不会存入数据库):

  1. 在createUser方法中添加临时属性:
$test = User::firstOrCreate([
    // 现有字段配置
]);
// 临时添加明文密码属性
$test->plain_password = $randomPass;

UserCreated::dispatch($test);
  1. 监听器中直接读取该属性:
public function handle(UserCreated $event)
{
    $user = $event->user;
    Mail::to($user->email)->send(new SendUserMail([
        'user' => $user,
        'password' => $user->plain_password
    ]));
}

方法三:直接传递凭证数组给事件

如果不需要整个User模型,可直接传递包含明文密码和用户信息的数组:

  1. 修改UserCreated事件:
class UserCreated
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $credentials;

    public function __construct($credentials)
    {
        $this->credentials = $credentials;
    }
}
  1. 触发事件时传入包含用户模型和明文密码的数组:
$userCreds = [
    'email' => $this->email, 
    'password' => $randomPass,
    'user' => $test // 加入User模型用于邮件展示用户信息
];
UserCreated::dispatch($userCreds);
  1. 监听器中直接使用该数组:
public function handle(UserCreated $event)
{
    $creds = $event->credentials;
    Mail::to($creds['email'])->send(new SendUserMail($creds));
}

内容的提问来源于stack exchange,提问作者cdBreak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:20:35