Laravel5.8 入门系列三,添加注册邮箱验证

为了密码垃圾用户,一般在用户注册的时候都会对用户进行验证。这里我们在注册的时候填写了用户的邮箱,但在注册过程中并没有对用户邮箱的真实性进行验证,因此需要添加一个邮件验证机制。

整体思路是用户注册的时候,向用户的邮箱发送一个带有特殊验证串的链接,用户点击链接之后,用户验证通过,然后就可以正常登录的,否则用户登录的时候提示用户需要邮件进行激活。

修改用户数据表

为了实现上面的功能,需要在用户表中添加两个字段,activity_token,activity_expire,is_activity分别表示激活字符串,激活验证过期时间,是否激活标记。

对于数据库的修改,可以使用Laravel创建数据迁移文件,并执行数据迁移完成。

在根目录下,执行下面的命令,创建一个对users表的数据库迁移文件

php artisan make:migration alter_users_table --table=users

上面的命令会在database/migrations目录下新增一个类似2019_09_08_082359_alter_users_table.php的文件名,前面是日期加一个随机数。

修改你的数据库迁移文件,修改up方法如下:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('activity_token')->comment('激活验证token');
        $table->dateTime('activity_expire')->comment('激活过期时间');
        $table->tinyInteger('is_activity')->default(0)->comment('是否激活1是,0否');
    });
}

执行数据库迁移命令php artisan migrate

插入用户数据添加激活token,激活过期时间

用户注册的控制器的文件为app\Http\Controller\Auth\RegisterController.php
所有的业务逻辑,都是通过Illuminate\Foundation\Auth\RegistersUsers这个trait实现的。到目前为止,这个文件没有太多的内容,基本上都是Laravel本身就已经完成了大部分逻辑。

修改RegisterController中的create方法,添加activity_token,email_verified_at的赋值逻辑。

//注意需要添加 use Illuminate\Support\Facades\Date; 
protected function create(array $data)
{
    return User::create([
        'activity_token'=>\Str::random(60),
        'activity_expire'=>Date::now('+1 days'),
        'name' => $data['name'],
        'email' => $data['email'],
        'password' => Hash::make($data['password']),
    ]);
}

注意,这里我们只是把数据设置进去了,还要保证模型中这两个字段是允许填充的。修改app\User.php文件,在$fillable属性数组中添加activity_token,email_verified_at两个字段。修改后内容如下:

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

这样,我们就把我们的激活串,以及激活过期时间设置到注册用户表中去了。赶紧去尝试注册一个新用户,看看数据表中是否有了activity_token数据了。

给用户邮箱发送邮件

我们期望的是在用户数据保存到数据库之后,向用户邮箱发送一封验证邮件,然后跳转到一个页面提示用户去邮箱激活。

Laravel的邮箱配置文件在config/mail.php中。这里我们还是通过修改本地环境变量修改邮箱配置。修改环境变量下面的内容:

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io  ## smtp地址,qq 地址为 smtp.qq.com
MAIL_PORT=2525   ## smtp端口,qq 462
MAIL_USERNAME=null  ## 邮箱名,qq 自己邮箱地址
MAIL_PASSWORD=null  ## 密码,qq邮箱需要开通smtp后的临时码
MAIL_ENCRYPTION=null  ## 如果服务商加密方式是SSL,比如qq,填写SSL

为了实现注册发送邮件功能更,我们需要覆盖register方法。在RegisterController.php中添加以下方法,内容如下:

public function register(Request $request)
{
    $this->validator($request->all())->validate();
    event(new Registered($user = $this->create($request->all())));
    //发送邮件
    \Mail::raw(
    '请在'.$user->activity_expire.'前,点击链接激活您的账号'.route('user.activity',['token'=>$user->activity_token])
    ,function($message) use($user){
        $message->from('1035308417@qq.com','老王Laravel入门')
        ->subject('注册激活邮件')
        ->to($user->email);
    });
    //显示注册激活提示信息
    return view('auth.registed',['user'=>$user]);
}

上面的内容需一个激活链接路由,我们先直接在路由文件中随便添加。在路由文件route/web.php总添加激活路由:

Route::get('activity/{token}','Auth\RegisterController@activity')->name('user.activity');

添加一个提示信息的试图文件resource/views/auth/registed.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Register') }}</div>

                <div class="card-body">
                    激活链接已发送至您的邮箱{{$user->email}},请于{{$user->activity_expire}}前激活您的账户。
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

这样,所有需要的工作都做完了,注册账号可以看到邮箱中有激活邮件
Laravel

同时界面上显示提示内容:
Laravel

激活用户

用户注册成功,收到邮件之后,需要通过点击链接激活用户。上面我们已经添加了路由user.activity。所以只需要在RegisterController中添加activity方法,通过token验证用户,同时在activityres试图文件上提示用户激活结果。


function activity($token){
    $user = User::find(['activity_token'=>$token]);
    $res = false;
    if($user && strtotime($user->activity_expire)>time())
    {
        $user->is_activity = 1;
        $res = $user->save();
    }
    return view('auth.activityres',['res'=>$res]);
}

试图文件resources/views/auth/activityres.blade.php内容如下:

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Activity Result') }}</div>

                <div class="card-body">
                    @if($res === false)
                        该链接已失效,请重新<a href="{{route('register')}}">注册>></a>
                    @else
                        您的账号已经激活,请<a href="{{route('login')}}">登录>></a>
                    @endif
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

对于任何无效的链接(无效,过期,或者已经激活的)都提示激活失败,请重新注册。

Laravel

限制未激活用户的登录

到目前为止,我们都是在修改注册时候的逻辑。但是不要忘了,之前的登录逻辑是没有验证用户邮箱是否激活。因此在用户登录的时候需要添加对用户是否激活逻辑的验证。

用户登录的控制器为app\Http\Controller\Auth\LoginController,其中,主要的业务逻辑由Illuminate\Foundation\Auth\AuthenticatesUsers 这个trait实现。我们需要在尝试登录的时候添加用户是否激活的判断条件,因此我们复制AuthenticatesUsers中的attempLogin方法到LoginController中。修改内容如下:

/**
 * Attempt to log the user into the application.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return bool
 */
protected function attemptLogin(Request $request)
{
    return $this->guard()->attempt(
        [
            'email'=>$request->email,
            'password'=>$request->password,
            'is_activity'=>1,
        ], $request->filled('remember')
    );
}

这样我们就限制了只有激活的用户才能登录。

Laravel

本作品采用《CC 协议》,转载必须注明作者和本文链接
写PHP的老王
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!