邮件验证功能

设置

在接下来的功能开发中,我们将使用 Laravel 来发送邮件,为了方便测试,我们需要对环境配置文件 .env 进行配置,使用 log 邮件驱动的方式来调试邮件发送功能,这么做的好处是邮件并不会真正被发送出去,而是会出现在 storage/logs/laravel.log 文件中,该文件记录着一切 Laravel 在运行时的日志信息,有助于我们在本地进行开发调试。

.env

.
.
.
APP_URL=http://sample.app
.
.
.
MAIL_DRIVER=log
.
.
.

激活路由

我们需要为用户的激活功能设定好路由,该路由将附带用户生成的激活令牌,在用户点击链接进行激活之后,我们需要将激活令牌通过路由参数传给控制器的指定动作,最终生成的激活链接例子如下:

http://sample.app/signup/confirm/O1TTEr3faVq4fpzFXaOVQD4EAO9mQL

由上面链接我们可以推导出路由的定义应该如下。

routes/web.php

name('home');
Route::get('/help', 'StaticPagesController@help')->name('help');
Route::get('/about', 'StaticPagesController@about')->name('about');

Route::get('signup', 'UsersController@create')->name('signup');
Route::resource('users', 'UsersController');

Route::get('login', 'SessionsController@create')->name('login');
Route::post('login', 'SessionsController@store')->name('login');
Route::delete('logout', 'SessionsController@destroy')->name('logout');

Route::get('signup/confirm/{token}', 'UsersController@confirmEmail')->name('confirm_email');

在 Laravel 中,我们使用视图来构建邮件模板,在用户查收邮件时,该模板将作为内容展示视图。接下来我们需要创建一个用于渲染注册邮件的 confirm 视图。

resources/views/emails/confirm.blade.php




  
  注册确认链接


  

感谢您在 Sample 网站进行注册!

请点击下面的链接完成注册: {{ route('confirm_email', $user->activation_token) }}

如果这不是您本人的操作,请忽略此邮件。

登录时检查是否已激活

当用户没有激活时,则视为认证失败,用户将会被重定向至首页,并显示消息提醒去引导用户查收邮件。

app/Http/Controllers/SessionsController.php

validate($request, [
           'email' => 'required|email|max:255',
           'password' => 'required'
       ]);

       $credentials = [
           'email'    => $request->email,
           'password' => $request->password,
       ];

       if (Auth::attempt($credentials, $request->has('remember'))) {
           if(Auth::user()->activated) {
               session()->flash('success', '欢迎回来!');
               return redirect()->intended(route('users.show', [Auth::user()]));
           } else {
               Auth::logout();
               session()->flash('warning', '你的账号未激活,请检查邮箱中的注册邮件进行激活。');
               return redirect('/');
           }
       } else {
           session()->flash('danger', '很抱歉,您的邮箱和密码不匹配');
           return redirect()->back();
       }
    }
    .
    .
    .
}

发送邮件

接下来我们要开始使用邮箱发送功能,在 Laravel 中,可以通过 Mail 接口的 send 方法来进行邮件发送,示例如下:

$view = 'emails.confirm';
$data = compact('user');
$from = '[email protected]';
$name = 'Aufree';
$to = $user->email;
$subject = "感谢注册 Sample 应用!请确认你的邮箱。";

Mail::send($view, $data, function ($message) use ($from, $name, $to, $subject) {
    $message->from($from, $name)->to($to)->subject($subject);
});

Mail 的 send 方法接收三个参数。

  • 第一个参数是包含邮件消息的视图名称。
  • 第二个参数是要传递给该视图的数据数组。
  • 最后是一个用来接收邮件消息实例的闭包回调,我们可以在该回调中自定义邮件消息的发送者、接收者、邮件主题等信息。

接下来让我们为用户控制器定义一个 sendEmailConfirmationTo 方法,该方法将用于发送邮件给指定用户。我们会在用户注册成功之后调用该方法来发送激活邮件,具体代码实现如下。

app/Http/Controllers/UsersController.php

validate($request, [
            'name' => 'required|max:50',
            'email' => 'required|email|unique:users|max:255',
            'password' => 'required|confirmed|min:6'
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => bcrypt($request->password),
        ]);

        $this->sendEmailConfirmationTo($user);
        session()->flash('success', '验证邮件已发送到你的注册邮箱上,请注意查收。');
        return redirect('/');
    }
    .
    .
    .
    protected function sendEmailConfirmationTo($user)
    {
        $view = 'emails.confirm';
        $data = compact('user');
        $from = '[email protected]';
        $name = 'Aufree';
        $to = $user->email;
        $subject = "感谢注册 Sample 应用!请确认你的邮箱。";

        Mail::send($view, $data, function ($message) use ($from, $name, $to, $subject) {
            $message->from($from, $name)->to($to)->subject($subject);
        });
    }
}

请注意我们需要调用 use Mail 来引入邮件相关的操作方法。通过上面代码可以看到,我们把之前用户注册成功之后进行的登录操作:

Auth::login($user);

替换为了激活邮箱的发送操作:

$this->sendEmailConfirmationTo($user);

注册成功提示语改为查看邮箱的提示语。在激活邮件发送成功之后,我们还会将用户重定向至首页,而并非之前的用户个人页。

激活功能

现在的邮箱发送功能已经能够正常使用,接下来让我们完成前面定义的 confirm_email 路由对应的控制器方法 confirmEmail,来完成用户的激活操作。并且在 __construct 方法里开启未登录用户访问权限。

app/Http/Controllers/UsersController.php

middleware('auth', [
            'except' => ['show', 'create', 'store', 'index', 'confirmEmail']
        ]);
        .
        .
        .
    }
    .
    .
    .
    public function confirmEmail($token)
    {
        $user = User::where('activation_token', $token)->firstOrFail();

        $user->activated = true;
        $user->activation_token = null;
        $user->save();

        Auth::login($user);
        session()->flash('success', '恭喜你,激活成功!');
        return redirect()->route('users.show', [$user]);
    }
}

Auth 中间件黑名单中,我们增加了 confirmEmail 来开启未登录用户的访问。

在 confirmEmail 中,我们会先根据路由传送过来的 activation_token 参数从数据库中查找相对应的用户,Eloquent 的 where 方法接收两个参数,第一个参数为要进行查找的字段名称,第二个参数为对应的值,查询结果返回的是一个数组,因此我们需要使用 firstOrFail 方法来取出第一个用户,在查询不到指定用户时将返回一个 404 响应。在查询到用户信息后,我们会将该用户的激活状态改为 true,激活令牌设置为空。最后将激活成功的用户进行登录,并在页面上显示消息提示和重定向到个人页面。

如果我们尝试注册一个新用户,便能够在 laravel.log 文件的最后面,看到有以下相关的内容输出。

storage/logs/laravel.log

在浏览器上尝试访问在 laravel.log 文件中输出的激活链接,则可以看到新注册用户被成功激活。

你可能感兴趣的:(邮件验证功能)