用户注册时,将发送一封电子邮件进行确认
但是当用户更新电子邮件时如何发送通知?
就像他注册时一样
更新2024/4/8
此链接对此进行了解释 https://laravel.com/docs/11.x/mail
摘要示例:
为了测试,您可以将
MAIL_MAILER
中 log
的值设置为 .env
,以查看 /storage/log/laravel.log 中电子邮件何时发送。
一个简单的例子,不需要打包,为了让用户在更改邮箱后收到确认链接,我们可以这样进行:
在
routes/web.php
<?php
use App\Mail\EmailConfirmation;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Route;
Route::middleware('auth')->group(function(){
Route::get('change-email', function(){
$email = Auth::user()->email;
return view('change-email', compact('email'));
})->name('change-email');
Route::post('change-email-post', function(Request $request)
{
$validatedData = $request->validate([
'email' => 'required|email',
]);
$updated = User::where(['id' => Auth::id()])->update($validatedData);
if($updated) {
$key = setVerifyToken($validatedData['email']);
$link = route('verify', ['key' => $key]);
Mail::to(Auth::user())->send(new EmailConfirmation(Auth::user(), $link));
session()->flash('message', 'Your email is update, please check your inbox to confirm the new email');
} else {
session()->flash('message', 'Cannot update your email, try again after 60 seconds');
}
return redirect()->route('change-email', ['email' => $validatedData['email']]);
})->name('change-email-post');
});
Route::get('verify/{key}', function($key){
$email = getVerifyValue($key, $state);
if(! $state) {
$message = $email;
} else {
$user = User::where(['email' => $email, 'email_verified_at' => null])->update([
'email_verified_at' => Carbon::now(),
]);
if($user) {
$message = "Email is verified";
} else {
$message = "Unverified user not found";
}
}
return view('verify', compact('message'));
})->name('verify');
change-email
路径用于显示表单
change-email-post
路线用于发送确认电子邮件和电子邮件更新
verify path
用于验证电子邮件。
那就最好创建一个助手,方便工作 当然,你可以在任何你想要的地方定义函数。ه 在
composer.json
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
},
"files": [
"app\\helpers.php"
]
},
然后创建u200d
app/helpers.php
文件
然后输入以下命令:
composer dump-autoload
然后创建app/helpers.php文件
在应用程序/helpers.php中
<?php
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
if(! function_exists('setVerifyToken')) {
function setVerifyToken($account){
// '<str>' skeleton key
// '<email>:<expire link>'
$key = base64_encode(Hash::make(Str::random(30).$account));
$expire = time() + 600; // 10 minute
Cache::put($key, $account.':'.$expire);
return $key;
}
}
if(! function_exists('getVerifyValue')) {
function getVerifyValue(string $key, &$state) {
if(! Cache::has($key)) {
$state = false;
return "key not found";
}
[$email, $expire] = explode(':', Cache::get($key));
if($expire < time()) {
$state = false;
return "key is expired"; //expired
}
$state = true;
return $email;
}
}
setVerifyToken函数使用Hash::make为我们创建一个哈希并创建一个字符串,该字符串的第一部分是30个随机字符,第二部分是请求的帐户字符串,这样两个不同电子邮件的两个相似链接的概率干扰接近于零。达到目标
缓存后返回$key的值,可以使用getVerifyValue函数重置并确认$key的正确性。
我们可以使用邮件发送电子邮件
php artisan make:mail EmailConfirmation
在
app/Mail/EmailConfirmation.php
<?php
namespace App\Mail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class EmailConfirmation extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public function __construct(public User $user, public $link)
{
//
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
from: config('mail.from.address'),
subject: 'Email Confirmation',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'email-confirmation',
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}
然后制作刀片模板;
在
resources/views/change-email.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form method="POST" action="{{ route('change-email-post') }}">
@csrf
<input name="email" value="{{ $email }}" type="email">
<button type="submit">update</button>
@if(session()->has('message'))
<li>{{session()->get('message')}}</li>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
</form>
</body>
</html>
在
resources/views/email-confirmation.blade.php
Hello {{ $user->name }}
Your {{ $user->email }} email needs confirmation
Please confirm your link by clicking on the link below
{{ $link }}
在
resources/views/verify.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
{{ $message }};
</body>
</html>
如果你想重新验证用户的电子邮件,你应该将他的 email_verified_at 设置为 null 然后调用 sendEmailVerificationNotification 方法。
在您的用户模型(位于 app\user 中)添加此方法:
public function sendNewVerification() {
$this->email_verified_at =null;
$this->sendEmailVerificationNotification();
}
并在控制器中调用它。
希望这会起作用。