简介
许多Web应用要求用户在使用应用前验证其邮箱地址。Laravel无需您为每个应用手动重新实现此功能,而是提供了便捷的内置服务来发送与验证邮箱验证请求。
想快速上手?在全新的Laravel应用中安装其中一个Laravel应用入门套件。入门套件会为您搭建整个身份验证系统,包括邮箱验证支持。
模型准备
在开始之前,请确认您的App\Models\User模型实现了Illuminate\Contracts\Auth\MustVerifyEmail契约:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
// ...
}为模型添加该接口后,新注册的用户会自动收到一封包含邮箱验证链接的邮件。这一过程能无缝完成,是因为Laravel自动为Illuminate\Auth\Events\Registered事件注册了Illuminate\Auth\Listeners\SendEmailVerificationNotification监听器。
如果您没有使用入门套件,而是手动在应用中实现注册功能,那么请确保在用户注册成功后触发Illuminate\Auth\Events\Registered事件:
use Illuminate\Auth\Events\Registered;
event(new Registered($user));数据库准备
接下来,您的users表必须包含email_verified_at列,用于存储用户邮箱地址的验证日期与时间。通常,此列已包含在Laravel默认的0001_01_01_000000_create_users_table.php数据库迁移文件中。
路由
要正确实现邮箱验证,需要定义三条路由。第一条路由用于向用户展示提示,告知他们应点击Laravel在注册后发送的验证邮件中的邮箱验证链接。
第二条路由用于处理用户点击邮件中邮箱验证链接时生成的请求。
第三条路由用于当用户意外丢失首次验证链接时,重新发送验证链接。
邮箱验证提示
如前所述,需要定义一条路由,返回一个视图,引导用户点击Laravel在注册后发送的邮箱验证链接。当用户在未先验证邮箱地址的情况下尝试访问应用其他部分时,系统将向其展示该视图。请注意,只要您的App\Models\User模型实现了MustVerifyEmail接口,验证链接就会自动发送给用户:
Route::get('/email/verify', function () {
return view('auth.verify-email');
})->middleware('auth')->name('verification.notice');返回邮箱验证提示的路由应命名为verification.notice。为路由设置此确切名称至关重要,因为Laravel自带的verified中间件会在用户未验证邮箱地址时,自动重定向到该路由名称。
手动实现邮箱验证时,您需要自行定义验证提示视图的内容。若希望获得包含所有必要身份验证与验证视图的脚手架,请查看Laravel应用入门套件。
邮箱验证处理程序
接下来,我们需要定义一条路由,用于处理用户点击邮件中邮箱验证链接时生成的请求。该路由应命名为verification.verify,并添加auth和signed中间件:
use Illuminate\Foundation\Auth\EmailVerificationRequest;
Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
$request->fulfill();
return redirect('/home');
})->middleware(['auth', 'signed'])->name('verification.verify');继续之前,先仔细研究这条路由。首先,您会注意到使用的是EmailVerificationRequest请求类型,而非常见的Illuminate\Http\Request实例。EmailVerificationRequest是Laravel自带的表单请求。该请求会自动完成对请求id与hash参数的验证。
接下来,可直接调用请求的fulfill方法。该方法会调用已认证用户的markEmailAsVerified方法,并触发Illuminate\Auth\Events\Verified事件。默认的App\Models\User模型可通过Illuminate\Foundation\Auth\User基类使用markEmailAsVerified方法。用户邮箱地址验证完成后,您可将其重定向到任意位置。
重发验证邮件
用户有时会遗失或误删邮箱地址验证邮件。为解决这一问题,您可定义一条路由,允许用户请求重发验证邮件。之后,在验证提示视图中添加一个简单的表单提交按钮,即可向该路由发起请求:
use Illuminate\Http\Request;
Route::post('/email/verification-notification', function (Request $request) {
$request->user()->sendEmailVerificationNotification();
return back()->with('message', 'Verification link sent!');
})->middleware(['auth', 'throttle:6,1'])->name('verification.send');保护路由
可使用路由中间件,仅允许已验证用户访问指定路由。Laravel内置了verified中间件别名,该别名对应Illuminate\Auth\Middleware\EnsureEmailIsVerified中间件类。由于此别名已由Laravel自动注册,您只需在路由定义中附加verified中间件即可。通常,该中间件会与auth中间件配合使用:
Route::get('/profile', function () {
// Only verified users may access this route...
})->middleware(['auth', 'verified']);若未验证用户尝试访问应用了该中间件的路由,系统会自动将其重定向到verification.notice命名路由。
自定义
验证邮件自定义
尽管默认的邮箱验证通知能满足大多数应用的需求,但Laravel允许您自定义邮箱验证邮件内容的构建方式。
开始之前,请向Illuminate\Auth\Notifications\VerifyEmail通知提供的toMailUsing方法传入一个闭包。该闭包会接收接收通知的可通知模型实例,以及用户需访问以验证邮箱的签名邮箱验证URL。闭包应返回Illuminate\Notifications\Messages\MailMessage的实例。通常,您应在应用AppServiceProvider类的boot方法中调用toMailUsing方法:
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
// ...
VerifyEmail::toMailUsing(function (object $notifiable, string $url) {
return (new MailMessage)
->subject('Verify Email Address')
->line('Click the button below to verify your email address.')
->action('Verify Email Address', $url);
});
}若想进一步了解邮件通知,请查阅邮件通知文档。
事件
使用Laravel应用入门套件时,Laravel会在邮箱验证过程中触发Illuminate\Auth\Events\Verified事件。如果您在应用中手动处理邮箱验证,可在验证完成后手动触发这些事件。