忘记密码是应用中常见的场景之一,Laravel 5.1也提供了对密码重置的支持,我们只需稍微做一下配置即可轻松实现重置密码。
通过给用户注册邮箱发送包含特定令牌的重置密码链接,然后用户登录邮箱通过访问该重置密码链接实现密码的重置。
CanResetPasswordContract
契约并使用CanResetPassword
trait的User
模型(Laravel自带)password_resets
(Laravel自带该表对应迁移文件,上一节中已一并创建)Laravel自带了用于密码重置的控制器Auth\PasswordController
,和上一节提到的AuthController
位于统一目录下。重置密码相关的业务逻辑都是通过该控制器中使用的ResetsPasswords
trait来实现的。下面我们在routes.php
中为重置密码定义相关路由规则:
// 发送密码重置链接路由 Route::get('password/email', 'Auth\PasswordController@getEmail'); Route::post('password/email', 'Auth\PasswordController@postEmail'); // 密码重置路由 Route::get('password/reset/{token}', 'Auth\PasswordController@getReset'); Route::post('password/reset', 'Auth\PasswordController@postReset');
定义好路由之后我们为get请求定义对应视图文件,首先创建发送密码重置链接路由对应视图resources/views/auth/password.blade.php
:
<form method="POST" action="/password/email"> {!! csrf_field() !!} <div> Email <input type="email" name="email" value="{{ old('email') }}"> </div> <div> <button type="submit"> 发送密码重置链接 </button> </div> </form>
然后创建重置密码路由对应视图resources/views/auth/reset.blade.php
:
<form method="POST" action="/password/reset"> {!! csrf_field() !!} <input type="hidden" name="token" value="{{ $token }}"> <div> Email:<input type="email" name="email" value="{{ old('email') }}"> </div> <div> 新密码:<input type="password" name="password"> </div> <div> 确认密码:<input type="password" name="password_confirmation"> </div> <div> <button type="submit"> 重置密码 </button> </div> </form>
此外我们还要创建一个额外视图——发送密码重置链接的邮件模板视图resources/views/emails/password.blade.php
,用于为该邮件提供视图模板:
点击这里重置密码: {{ url('password/reset/'.$token) }}
如果该邮件模板视图文件路径位于其他地方,不要忘了配置config/auth.php
中的password.email
值与新路径对应。
接下来我们要做的是配置相关文件实现邮件发送功能为下一步测试做准备。
Laravel使用SwiftMailer库提供的邮件API实现邮件操作,详情可查看邮件文档,这里我们仅作简单配置实现邮件发送,邮件配置文件是config/mail.php
:
<?php return [ 'driver' => env('MAIL_DRIVER', 'smtp'), 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 'port' => env('MAIL_PORT', 587), 'from' => ['address' => null, 'name' => null], 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), 'sendmail' => '/usr/sbin/sendmail -bs', 'pretend' => false, ];
可见大部分配置在.env
文件中设置,这里我的.env
文件配置如下:
MAIL_DRIVER=smtp MAIL_HOST=smtp.163.com MAIL_PORT=25 MAIL_USERNAME=yaojinbu@163.com MAIL_PASSWORD=mypassword MAIL_ENCRYPTION=null
我使用的是163邮箱,其它邮箱参考对应邮箱相关设置项,并将自己的账户信息填写到MAIL_USERNAME
和MAIL_PASSWORD
。
此外我们还要配置mail.php
中的from
配置如下:
'from' => ['address' => 'yaojinbu@163.com ', 'name' => 'Laravel学院'],
这里只需要将address
和.env
文件中的MAIL_USERNAME
值相匹配即可。至于name
值就是邮箱中发件人名称,可自定义。
做好这一步配置后,接下来即可测试密码重置了。
在浏览器中访问http://laravel.app:8000/password/email
,页面显示如下:
在Email输入框中填写你的注册邮箱,点击“发送密码重置链接”,然后去邮箱中查看收件箱,如果发送成功,可收到一封内容如下的密码重置邮件:
点击这里重置密码: http://laravel.app:8000/password/reset/96c652e4885591c7ecfcb4f1ecc6f9b877ac1a2ab445e7fb45a89fdfc7283585
此时数据表password_resets
中也新增了一条记录,用于保存重置链接令牌:
该令牌默认保存一个小时,要修有效期,可通过编辑config/auth.php
中password.expire
来实现。
我们将重置密码邮件中的链接拷贝出来粘贴到浏览器地址栏回车,页面显示内容如下:
填写该表单后点击重置密码按钮即可完成密码重置。
密码重置成功后,默认跳转链接为/home
,我们可以在PasswordController
中通过设置$redirectTo
/$redirectPath
属性的值修改该跳转链接:
protected $redirectPath = '/profile';
这样重置成功后会跳转到http://laravel.app:8000/profile
:
test登录成功!
同时password_resets
中的对应记录也会被删除。
好了,下次登录就可以使用新密码进行登录认证了。