本小节将介绍一下,邮箱验证的发送及校验的过程。

    修改发送邮件配置信息 .env
MAIL_DRIVER=smtp
MAIL_HOST=smtp.qq.com
MAIL_PORT=465
MAIL_USERNAME=***@qq.com
MAIL_FROM_ADDRESS=***@qq.com
MAIL_PASSWORD=***
MAIL_ENCRYPTION=ssl

其中,MAIL_PASSWORD是邮件服务器提供的。这里是qq邮箱为例,进入设置在账户里,先开启smtp服务,用绑定qq的手机号发送一条指定的短信,就会获取到。MAIL_USERNAME和MAIL_FROM_ADDRESS某些邮件服务器要求保持一致,否则会出现501码。

    创建验证邮件通知类

>$ php artisan make:notification EmailVerificationNotification

完善该文件 \App\Notifications\EmailVerificationNotification.php  的 toMail 方法:

    /**
     * 发送邮件时会调用此方法来构建邮件内容
* Get the mail representation of the notification.
*
* @param mixed $notifiable App\Models\User 对象
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{

// 保存邮件发送相关信息
// 使用Laravel内置Str类生成随机字符串
$token = Str::random().uniqid();
// 写入缓存 30分钟
$expireTime = 30;
Cache::set('email_verification_'.$notifiable->email, $token, $expireTime);

$url = route('email_verification.verify', ['email'=>$notifiable->email, 'token'=>$token]);
return (new MailMessage)
->greeting( $notifiable->name.'您好:' )
->subject('恭喜,注册成功,请验证您的邮箱')
->line('请点击下方链接验证您的邮箱')
->action('验证', $url)
->line('感谢您的关注,我们将竭力服务。');
}

主要将一些验证信息写入到缓存供 \App\Notifications\EmailVerificationController.php 方法 verify 调用。

    编写控制器EmailVerificationController

目前,该控制器主要有两个方法。send 是用户手动触发发送邮件;verify 是验证邮件是否验证成功。

<?php
namespace App\Http\Controllers;

use App\Models\User;
use Exception;
use App\Notifications\EmailVerificationNotification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class EmailVerificationController extends Controller
{
/**
* 用户手动触发邮件事件
* @param Request $request
*/
public function send( Request $request )
{
$user = $request->user();
if ( $user->email_verified ) {
throw new Exception('你已经验证过了');
}
// 调用 notify() 方法用来发送我们定义好的通知类
$user->notify( new EmailVerificationNotification() );

return view('pages.success', ['msg'=>'邮件发送成功']);
}

/**
* 验证邮箱是否校验通过
* @param Request $request
* @throws Exception
*/
public function verify( Request $request )
{
$email = $request->input('email');
$token = $request->input('token');
if ( !$email || !$token ) {
throw new Exception('验证链接有误');
}

// 判断对应缓存是否存在
if ( !Cache::get('email_verification_'.$email) || Cache::get('email_verification_'.$email) != $token ) {
throw new Exception('验证链接不正确或链接过期');
}

// 验证用户是否存在
if ( !$user = User::where(['email'=>$email])->first() ) {
throw new Exception('用户不存在');
}

// 校验通过 删除缓存
Cache::forget('email_verification_'.$email);

// 修改用户状态【置为已验证】
$user->update(['email_verified'=>true]);

// 显示验证成功页面
return view('pages.success', ['msg'=>'恭喜,验证成功']);
}
}
    完善路由

Auth::routes( );

Route::get('/', 'PagesController@root')

->name('root');

Route::group(['middleware'=>'auth'], function() {
// 手动触发发送邮件
Route::get('/email_verification/send', 'EmailVerificationController@send')
->name('email_verification.send');

// 邮箱验证页面
Route::get('/email_verify_notice', 'PagesController@emailVerifyNotic')
->name('email_verify_notice');

// 邮箱逻辑校验
Route::get('/email_verification/verify', 'EmailVerificationController@verify')
->name('email_verification.verify');

// 开始验证邮箱
Route::group(['middleware'=>'email_verified'], function() {
Route::get('/test', function() {
return 'Your email is verified';
});
});
// 结束
});
    修改上一小节 email_verify_notice.blade.php

@extends('layouts.app')

@section('title', '邮箱验证')

@section('content')
<div class="panel panel-default">
<div class="panel-heading">
提示
</div>
<div class="panel-body text-center">
<h1>请先验证邮箱</h1>
<a class="btn btn-danger" href="{{ route('email_verification.send') }}">重新发送验证邮件</a>
</div>
</div>
@endsection

主要就是修改了,重新发送验证邮件,加了手动触发事件的路由。route('email_verification.send')

    新增验证成功页面 success.blade.php

@extends('layouts.app')

@section('title', '操作成功')

@section('content')
<div class="panel panel-default">
<div class="panel-heading">操作成功</div>
<div class="panel-body text-center">
<h1>{{ $msg }}</h1>
<a class="btn btn-primary" href="{{ route('root') }}">返回首页</a>
</div>
</div>
@endsection

至此,一个简单的用户注册发送邮箱验证的逻辑大体上实现了。下一小节,实现用户注册成功后,系统自动发送验证邮件。现在,结合前一小节整体梳理一下:

  1. 创建邮箱验证中间件;
  2. 路由中,将需要验证通过的页面写在中间件组里面;
  3. 中间件判断是否已验证,已验证直接通过。没验证,跳转到验证页面,用户点击验证按钮,手动触发发送事件;
  4. 用户从邮箱里点击预设好的url,进行校验,若通过,则验证成功。否则失败,刷新重试。
    由于能力有限,不足或有不解之处,希望在下方评论区与我讨论,共同提高 。