Laravel 邮箱认证

2022-09-14 14:51:33 浏览数 (1)

1.首先在UserModel引入邮箱认证相关功能

代码语言:javascript复制
<?php

namespace AppModels;

use IlluminateContractsAuthMustVerifyEmail as MustVerifyEmailContract;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
use IlluminateAuthMustVerifyEmail as MustVerifyEmailTrait;

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',
    ];
}

我们修改的User实现了 MustVerifyEmailContract 接口 查看其源码 vendor/laravel/framework/src/illuminate/Contracts/Auth/MustVerifyEmail

代码语言:javascript复制
<?php

namespace IlluminateContractsAuth;

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

    /**
     * Get the email address that should be used for verification.
     *获取发送邮件地址
     * @return string
     */
    public function getEmailForVerification();
}

在User内部我们添加了 trait MustVerifyEmailTrait 该trait实现 MustVerifyEmailContract接口

查看其源码 vendor/laravel/framework/src/illuminate/Auth/MustVerifyEmail.php

代码语言:javascript复制
<?php

namespace IlluminateAuth;

use IlluminateAuthNotificationsVerifyEmail;

trait MustVerifyEmail
{
    /**
     * Determine if the user has verified their email address.
     *检查用户邮箱是否认证
     * @return bool
     */
    public function hasVerifiedEmail()
    {
        return ! is_null($this->email_verified_at);
    }

    /**
     * Mark the given user's email as verified.
     *将用户标记为已认证
     * @return bool
     */
    public function markEmailAsVerified()
    {
        return $this->forceFill([
            'email_verified_at' => $this->freshTimestamp(),
        ])->save();
    }

    /**
     * Send the email verification notification.
     *发送email认证的消息通知
     * @return void
     */
    public function sendEmailVerificationNotification()
    {
        $this->notify(new VerifyEmail);
    }

    /**
     * Get the email address that should be used for verification.
     *获取发送邮件地址
     * @return string
     */
    public function getEmailForVerification()
    {
        return $this->email;
    }
}

我们要实现的功能是用户注册后发送认证邮件,我们查看laravel自带的 RegisterController控制器 appHttpControllersAuth/RegisterController

查看其源码发现加载了 RegistersUsers;

再次找到 RegisterUsers;

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

我们主要看 register方法

代码语言:javascript复制
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这里很关键,这里手动触发了 Registered 事件并传入了用户 我们可以在 app/Providers/EventServiceProvider.php 看到注册的事件监听器

代码语言:javascript复制
protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
    ];

该监听器的逻辑就是SendEmail.....类 我们在次找到 SendEmailVerificationNotification类的源码

vendor/laravel/framework/src/Illuminate/Auth/Listeners/SendEmailVerificationNotification.php

里面就一个handle方法

代码语言:javascript复制
<?php

namespace IlluminateAuthListeners;

use IlluminateAuthEventsRegistered;
use IlluminateContractsAuthMustVerifyEmail;

class SendEmailVerificationNotification
{
    /**
     * Handle the event.
     *
     * @param  IlluminateAuthEventsRegistered  $event
     * @return void
     */
    public function handle(Registered $event)
    {
        if ($event->user instanceof MustVerifyEmail && ! $event->user->hasVerifiedEmail()) {
            $event->user->sendEmailVerificationNotification();
        }
    }
}

该方法 判断user是否继承自 MustVerifyEmail 并且用户邮箱没有认证 如果两个条件都满足则调用发送邮件方法。

源码翻了个遍,相信你应该理解其原理了,接下来我们测试邮件发送功能

在.env 中我们将 MATL_DRIVER=smtp 修改为 log这样邮件会保存到 laravel.log文件中

使用其自带的用户注册逻辑与视图 通过命令 php artisan ui:auth 执行迁移文件 php artisan migrate

访问路由 {项目域名}/register

填写相关信息点击注册

在laravel.log中发现邮箱认证邮件

0 人点赞