通过 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
页面:
6 Comments
邮件内容可以自定义吗
当然可以了 在 User 模型类中覆盖 sendEmailVerificationNotification 方法实现即可 通过自己创建一个可邮寄类来解决
院长,我在 Laravel 5.8 版本里添加了强制邮箱认证,但是没有效果,不知道为啥呢?
User 模型实现了那个接口,用了 Trait,Auth 路由也加了参数 verify => true, 但是不知道为啥没有强制认证
home
路由启用邮箱判断中间件verified
了吗我想问一下,如果我也想在admin端添加邮箱认证功能怎么办
仿照前端逻辑做啊 不是一样的吗