[ Laravel 从入门到精通 ] 用户认证与授权系列 —— 通过 Laravel 内置脚手架快速实现邮箱验证功能

之前我们陆续介绍了基于 Web 路由和 API 路由的各种认证实现,在 Laravel 5.7 框架中还内置支持了邮箱验证功能,邮箱验证从一定程度上损耗了用户体验,需要用户验证注册邮箱后才能访问认证路由,但是可以有效避免垃圾用户,从长期来看对系统生态来说是利大于弊的。下面我们就 Laravel 框架内置的邮箱验证功能演示下如何使用。

路由配置

首先,在 routes/web.php 路由文件中修改之前定义的内置认证路由如下:

Auth::routes(['verify' => true]);
Route::get('/home', 'HomeController@index')->name('home')->middleware('verified');

Auth::routes 中传入 ['verify' => true] 参数表示注册邮箱验证相关路由:

第一个路由 email/verify 用于注册成功后跳转到邮箱待验证页面,或者未验证邮箱用户登录后跳转页面,在该页面可以点击链接重新发送验证邮件。

第二个路由 email/verify/{id} 用于从收到的验证邮件中点击链接访问该路由来完成邮箱验证。

最后一个路由 email/resend 显然是用于重新发送验证邮件到注册邮箱的。

/home 路由中应用了一个系统内置的中间件 verified,如果用户未验证邮箱,访问该路由会跳转到邮箱验证页面。

数据库考量

我们以前台用户为例演示邮箱验证功能,对应的用户表是 users,Laravel 5.7 默认在 users 表对应迁移类中新增了一个 email_verified_at 字段,用于判断用户是否已经验证邮箱:

$table->timestamp('email_verified_at')->nullable();

如果没有验证邮箱,该字段为 null,否则为验证时间。该字段在我们前面运行 php artisan migrate 的时候已经插入到 users 表中了。

User 模型

接下来,模型类 User 需要实现 Illuminate\Contracts\Auth\MustVerifyEmail 接口,其中包含了三个方法:

interface MustVerifyEmail
{
    /**
     * Determine if the user has verified their email address.
     *
     * @return bool
     */
    public function hasVerifiedEmail();

    /**
     * Mark the given user's email as verified.
     *
     * @return bool
     */
    public function markEmailAsVerified();

    /**
     * Send the email verification notification.
     *
     * @return void
     */
    public function sendEmailVerificationNotification();
}

hasVerifiedEmail 用于判断当前用户是否已经验证邮箱,markEmailAsVerified 方法用于用户验证邮箱后填充数据表 email_verified_at 字段,sendEmailVerificationNotification 用于在新用户注册或重发验证邮件时给对应用户发送邮箱验证邮件。

我们不需要手动实现这些方法,Laravel 底层为我们提供了一个 \Illuminate\Auth\MustVerifyEmail Trait,其中已经提供了上述三个方法的实现,我们只需在 User 模型类中使用它即可:

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable implements MustVerifyEmail
{
    use HasApiTokens, Notifiable, \Illuminate\Auth\MustVerifyEmail;

    ...

视图模板

在我们前面运行 php artisan make:auth 命令时,就已经为邮箱验证页面创建了对应的视图模板 resources/views/auth/verify.blade.php,该视图模板用于渲染用户未验证邮箱时登录后跳转页面。

这样,我们不需要编写任何业务代码,通过系统内置的脚手架就完成了整个邮箱验证功能。

邮箱配置

在测试邮箱验证功能之前,还要配置邮件发送,因为验证邮箱需要在注册邮箱中点击验证链接。关于这一块功能,可以参考博客项目邮件发送功能实现教程.env 进行配置。邮件发送逻辑是在 User 模型类的 sendEmailVerificationNotification 中完成的,无需手动编写。

邮箱验证流程测试

首先,我们测试一个新注册用户的邮箱验证流程,打开注册页面 http://blog.test/register,填写注册信息:

然后点击注册按钮「Register」,之前没有启用邮箱验证功能时,会直接跳转到 http://blog.test/home 页面,现在由于我们在 /home 路由中启用了邮箱验证判断中间件,在判定该用户尚未验证邮箱后,页面会跳转到邮箱验证页面 http://blog.test/email/verify

这时候,可以到注册邮箱收件箱收取邮箱验证邮件(如果没有去垃圾邮箱看看,都没有可以尝试点击上述页面的蓝色链接重新发送验证邮件),验证邮件内容如下:

点击中间那个「Verify Email Address」按钮即可完成邮箱验证,验证成功后页面会跳转到 /home 页面,表示验证成功:

这时候,去查看对应的数据库记录,也可以看到 email_verified_at 字段已经被填充,下次登录,就会判定用户已经验证过邮箱,从而直接跳转到 /home 页面:

学院君 has written 1155 articles

Laravel学院院长,终身学习者

积分:145497 等级:P12 职业:手艺人 城市:杭州

2 条回复

  1. 学院君 学院君 says:
    @ Sendio

    当然可以了 在 User 模型类中覆盖 sendEmailVerificationNotification 方法实现即可 通过自己创建一个可邮寄类来解决

登录后才能进行评论,立即登录?