SSPU-BBS中的邮箱认证

24 篇文章 1 订阅

虽然Laravel框架中默认自带了邮箱认证的功能,可以很方便地进行集成,但我还是想搞清楚其流程,所以今天花了一上午的时间进行理解。

首先,先定义邮箱认证的业务流程。

基本业务流程如下:

  1. 用户注册成功后,系统会自动发送一个附带“认证链接”邮件到用户邮箱;
  2. 用户打开“认证链接”即为激活账号,才可以正常访问系统;
  3. 用户在未通过邮箱进行验证的情况下,所有访问都会重定向到邮箱验证页面。

然后,再看邮箱认证的代码实现。

代码实现流程如下:

1.通过use Trait将Laravel自带的邮箱认证功能集成User模型中。这个Trait中包含邮箱认证的相关方法,包括user表中相关字段判断用户Email是否已认证、将其设置为已认证等。

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail as MustVerifyEmailContract;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Auth\MustVerifyEmail as MustVerifyEmailTrait;

//Contract契约,实现这个接口,继承此类将确保User遵守契约,拥有上面提到的四个方法
class User extends Authenticatable implements MustVerifyEmailContract
{
    //加载使用“MustVerifyEmail”Trait,这个Trait中包含邮箱认证的相关方法,包括user表中相关字段判断用户Email是否已认证、将其设置为已认证等
    use Notifiable, MustVerifyEmailTrait;  
    ......
}

2、分析laravel自带的RegisterController控制器,主要是用作邮箱认证的业务处理。其中使用了laravel的事件系统通过event(new Registered())触发Registered事件,然后使用listener对这个事件进行监听(所谓的监听就是将事件类与监听类之间建立关联)。

在RegisterController中引入了“RegistersUsers” Trait

use RegistersUsers;

在加载的Illuminate\Foundation\Auth\RegistersUsers Trait中register()方法对用户提交表单后的逻辑进行了处理。

    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());
    }

其中最关键的一点是使用了Laravel的事件系统,触发Registered事件。

注:laravel的事件系统就是一个简单的观察者模式,能够订阅和监听应用中发生的各种事件。事件系统有利用应用各个方面的解耦,因为单个事件可以拥有多个互不依赖的监听器。对于设计模式其实我也有点绕,后面再慢慢研究吧。

app/Providers/EventServiceProvider.php 文件的$listen属性中可以看到注册了Registered事件的监听器。

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

在SendEmailVerificationNotification类里对事件进行了处理,满足一定条件的话就发送认证邮件。

class SendEmailVerificationNotification
{
    //处理事件
    public function handle(Registered $event)
    {
        // 如果 user 是继承于 MustVerifyEmail 并且还未激活的话
        if ($event->user instanceof MustVerifyEmail && ! $event->user->hasVerifiedEmail()) {
            // 发送邮件认证消息通知(认证邮件)
            $event->user->sendEmailVerificationNotification();
        }
    }
}

3、通过Laravel中间件来过滤用户的所有请求,强制未注册用户进行认证,否则的话不能正常访问除认证页面外的其他页面。

创建一个中间件Middleware,对请求进行过滤,如果请求用户未认证的话,就跳转到邮件认证提醒的页面中。

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, 'Your email address is not verified.')
                        : redirect()->route('verification.notice');
        }

        return $next($request);
    }

中间件创建完成之后,需要在app/Http/Kernel.php中注册,这里要注意注册注册时机必须在StartSession后面,因为StartSession是启动会话,$request->user()的判断必须在会话已启动的情况下,否则永远都是false。

class Kernel extends HttpKernel
{
    .
    .
    .

    protected $middlewareGroups = [
        'web' => [
           ...
            \Illuminate\Session\Middleware\StartSession::class,
            ...
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\EnsureEmailIsVerified::class,      // 邮箱认证中间件
        ],
    ];
    .
    .
    .
}

大概流程就是以上三步,虽然内容不多,但还是需要好好理解理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值