当前位置 知且行 php laravel邮箱认证 下一篇:

laravel邮箱认证

继上文laravel用户认证,本篇将实现新用户需要邮箱验证才能注册成功

邮箱认证流程

分为两步:

  • 发送认证邮件 —— 将附带认证信息的『认证链接』发送到用户邮箱里;

  • 检测认证链接 —— 用户打开邮件,点击认证链接进入网站,程序检测 URL 中认证参数的合法性,并渲染对应的页面。

代码实现

routes/web.php 的认证路由改为:

Auth::routes(['verify' => true]);

app/User.php 引入 MustVerifyEmailTrait 即可完成邮箱验证

namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Auth\MustVerifyEmail as MustVerifyEmailTrait;
use Illuminate\Contracts\Auth\MustVerifyEmail as MustVerifyEmailContract;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements MustVerifyEmailContract
{
    use Notifiable, MustVerifyEmailTrait;

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

代码解析

分析laravel自带的app/Http/Controllers/Auth/RegisterController.php,注册调用的是:RegistersUsers这个trait的register方法:

vendor/laravel/framework/src/Illuminate/Foundation/Auth/RegistersUsers.php

public function register(Request $request)
{
    $this->validator($request->all())->validate();

    event(new Registered($user = $this->create($request->all())));

    $this->guard()->login($user);

    return $this->registered($request, $user)
                    ?: redirect($this->redirectPath());
}

使用 event(new Registered($user = $this->create($request->all()))); laravel的事件系统,表示触发了Registered事件,打开 app/Providers/EventServiceProvider.php 文件,此文件的 $listen 属性里我们可以看到注册了 Registered 事件的监听器:

protected $listen = [
    Registered::class => [
        SendEmailVerificationNotification::class,
    ],
];

打开 vendor/laravel/framework/src/Illuminate/Auth/Listeners/SendEmailVerificationNotification.php, 查看具体的监听器代码:

public function handle(Registered $event)
{
    if ($event->user instanceof MustVerifyEmail && ! $event->user->hasVerifiedEmail()) {
        $event->user->sendEmailVerificationNotification();
    }
}

因此只需要满足$event->user instanceof MustVerifyEmail && ! $event->user->hasVerifiedEmail()即可实现邮件认证功能

测试认证

开发环境中,可以将邮件内容写到日志中,便于调试。将 .envMAIL_DRIVER 设置为:

MAIL_DRIVER=log

然后新注册一个用户,提交表单后,查看storage/logs/laravel-2019-03-25.log目录下最新的日志文件,能看到laravel发送的验证内容

中间件验证权限

新注册的用户并没有进行邮箱验证,可以通过 dd(\Auth::user()->hasVerifiedEmail()); 测试是否已经验证

我们要实现的逻辑是:未验证的用户自动跳转到邮箱验证提示页面。可以借助中间件来实现此功能

$ php artisan make:middleware EnsureEmailIsVerified

自动创建 app/Http/Middleware/EnsureEmailIsVerified.php

public function handle($request, Closure $next)
{
    // 判断用户是否需要邮箱验证
    // 1. 用户已登录
    // 2. 未认证Email
    // 3. 访问的不是email验证相关url或者退出的url
    if ($request->user() && !$request->user()->hasVerifiedEmail() && !$request->is('email/*', 'logout')) {
        return $request->expectsJson() ? abort(403, '您的邮箱尚未验证') : redirect()->route('verification.notice');
    }
    return $next($request);
}

此时,我们再访问 http://www.test.com/home ,代码经由中间件时,符合邮箱验证条件,因此会被自动跳转到 http://www.test.com/email/verify

我们将log文件中的验证链接粘贴到浏览器访问,即可成功验证

小结

邮件认证的功能,laravel已经帮我们封装好了,只需进行简单的调用。难点在于理顺整个逻辑

转载必须注明出处:https://www.zhiqiexing.com/100.html

关于我

我希望能成为一个认真、有趣、创造更多价值的人
关注微信
微信扫一扫关注我

微信扫一扫关注我

返回顶部