设置
在接下来的功能开发中,我们将使用 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 文件中输出的激活链接,则可以看到新注册用户被成功激活。