管理员添加用户后,如何发送bcrypt加密前的原始密码至用户邮箱?
解决Laravel观察者发送邮件时密码为bcrypt密文的问题
你遇到的问题很典型——当created模型事件触发时,用户数据已经被保存到数据库,密码早已经被bcrypt加密完成,所以从模型实例里拿到的$customer->password自然是密文,没法直接发给用户做登录凭证。下面给你两个实用的解决方案:
方案一:在模型中临时存储明文密码(推荐)
这个方法不用改动你现有的观察者逻辑,只需要给Customer模型加个临时属性,在密码加密前把明文存下来:
- 在
Customer模型里添加一个不入库的临时属性:
// app/Models/Customer.php protected $plainPassword; // 注意:不要把这个属性加到$fillable数组里,不需要存到数据库
- 重写模型的密码赋值方法,先存明文再加密:
public function setPasswordAttribute($value) { $this->plainPassword = $value; // 先把明文密码存到临时属性 $this->attributes['password'] = bcrypt($value); // 再加密后存入数据库 }
- 回到你的观察者
created回调里,直接用临时属性获取明文密码即可:
self::created(function ($customer) { // 这里可以直接拿到明文密码啦 Mail::to($customer->email)->send(new YourMailTemplate($customer->email, $customer->plainPassword)); });
方案二:在创建用户时直接传递明文密码
如果不想修改模型,也可以在后台创建用户的控制器逻辑里保留明文密码,直接传递给邮件(或者通过自定义事件传给观察者):
- 后台控制器创建用户的代码示例:
// 管理员创建用户的控制器方法 public function store(Request $request) { $validated = $request->validate([ 'email' => 'required|email|unique:customers', 'password' => 'required|min:8', // 其他字段的验证规则 ]); $plainPassword = $validated['password']; // 先保存明文密码 $validated['password'] = bcrypt($plainPassword); // 再加密处理 $customer = Customer::create($validated); // 如果你不想用观察者,直接在这里发邮件就行 Mail::to($customer->email)->send(new YourMailTemplate($customer->email, $plainPassword)); // 要是想继续用观察者,可以触发一个自定义事件 event(new CustomerCreatedWithPassword($customer, $plainPassword)); }
- 若选择自定义事件,需要创建对应的事件类:
// app/Events/CustomerCreatedWithPassword.php class CustomerCreatedWithPassword { public $customer; public $plainPassword; public function __construct($customer, $plainPassword) { $this->customer = $customer; $this->plainPassword = $plainPassword; } }
之后让观察者监听这个自定义事件,就能拿到明文密码发送邮件了。
⚠️ 注意:不管用哪种方法,都要重视明文密码的安全——绝对不要把明文密码存入数据库,用完立即丢弃;同时确保邮件发送过程使用SSL/TLS加密,避免密码在传输过程中泄露。
内容的提问来源于stack exchange,提问作者Ali Özen
相关产品推荐
相关产品推荐

