使用数据库用户提供程序时如何在 Laravel 中创建密码重置方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42229086/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a password reset method in Laravel when using the Database User Provider
提问by short_coder
I've been searching the internet and have yet to find a solution to the following problem...
我一直在网上搜索,但还没有找到解决以下问题的方法......
We currently have a website developed using Laravel which the user table is a remote Microsoft SQL database. The driver in config/auth.php
has been set to "database". All is working fine except for the password reset functionality, which we get the following error:
我们目前有一个使用 Laravel 开发的网站,其用户表是一个远程 Microsoft SQL 数据库。驱动程序config/auth.php
已设置为“数据库”。除了密码重置功能外,一切正常,我们收到以下错误:
UnexpectedValueException in PasswordBroker.php line 238: User must implement CanResetPassword interface.
From my limited understanding of Laravel (this is my first experiance with Laravel), the Eloquent driver has support for the CanResetPassword functionality, however, this has not been implemented in the Database User Provider by Laravel, hence the error.
根据我对 Laravel 的有限理解(这是我第一次使用 Laravel),Eloquent 驱动程序支持 CanResetPassword 功能,但是,Laravel 尚未在 Database User Provider 中实现这一功能,因此出现错误。
So my question is thus, has anyone had a configuration where they have the driver to “Database” and implemented a reset password functionality? All the examples I have seen to date relate to using the Eloquent model, which from my understanding of Laravel is not an option since during the initial development we had to change the driver from Eloquent to database to get the remote Microsoft SQL server working in the first place. Moving the Microsoft SQL database to a local database is not an option I'm afraid.
所以我的问题是,有没有人有一个配置,他们有“数据库”的驱动程序并实现了重置密码功能?迄今为止我看到的所有示例都与使用 Eloquent 模型有关,根据我对 Laravel 的理解,这不是一个选项,因为在最初的开发过程中,我们不得不将驱动程序从 Eloquent 更改为数据库,以使远程 Microsoft SQL 服务器在第一名。将 Microsoft SQL 数据库移动到本地数据库恐怕不是一种选择。
Alternatively, if anyone has implemented another method of a user resetting their password using an email address I would be open to suggestions.
或者,如果有人实施了另一种用户使用电子邮件地址重置密码的方法,我愿意接受建议。
回答by EddyTheDove
To write your own password reset logic, you can still use the default migration that comes out of the box or simply create yours. The most important part is the token. Because you are making your own password reset, you have a couple of decisions to make:
要编写自己的密码重置逻辑,您仍然可以使用开箱即用的默认迁移或直接创建您的迁移。最重要的部分是令牌。因为您要自行重置密码,所以您需要做出几个决定:
- Will the token expire?
- Can a user use the same token multiple times?
- 令牌会过期吗?
- 一个用户可以多次使用同一个令牌吗?
You will need 2 pages, 4 different routes and 4 different functions in the same controller. The 'I forgot my password' page and the 'Reset password' page. In the first page, display a form where you take the user email. And post to the following controller.
在同一个控制器中,您将需要 2 个页面、4 个不同的路由和 4 个不同的功能。“我忘记了密码”页面和“重置密码”页面。在第一页中,显示您接收用户电子邮件的表单。并发布到以下控制器。
//to be added on top as use statements
use DB;
use Auth;
use Hash;
use Carbon;
use App\User;
public function sendPasswordResetToken(Request $request)
{
$user = User::where ('email', $request->email)-first();
if ( !$user ) return redirect()->back()->withErrors(['error' => '404']);
//create a new token to be sent to the user.
DB::table('password_resets')->insert([
'email' => $request->email,
'token' => str_random(60), //change 60 to any length you want
'created_at' => Carbon::now()
]);
$tokenData = DB::table('password_resets')
->where('email', $request->email)->first();
$token = $tokenData->token;
$email = $request->email; // or $email = $tokenData->email;
/**
* Send email to the email above with a link to your password reset
* something like url('password-reset/' . $token)
* Sending email varies according to your Laravel version. Very easy to implement
*/
}
Second part, when the user clicks on the link
第二部分,当用户点击链接时
/**
* Assuming the URL looks like this
* http://localhost/password-reset/random-string-here
* You check if the user and the token exist and display a page
*/
public function showPasswordResetForm($token)
{
$tokenData = DB::table('password_resets')
->where('token', $token)->first();
if ( !$tokenData ) return redirect()->to('home'); //redirect them anywhere you want if the token does not exist.
return view('passwords.show');
}
Display a page with a form containing 2 inputs
- New password password
or whateveer you want
- New password confirmation password_confirm
or whatever you want
The form should post to the same URL mapped to the following controller. Why? because we still need to use the token to find the actual user.
显示一个包含 2 个输入的表单的页面 - 新密码password
或任何你想要的 - 新密码确认password_confirm
或任何你想要的表单应该发布到映射到以下控制器的相同 URL。为什么?因为我们仍然需要使用令牌来查找实际用户。
public function resetPassword(Request $request, $token)
{
//some validation
...
$password = $request->password;
$tokenData = DB::table('password_resets')
->where('token', $token)->first();
$user = User::where('email', $tokenData->email)->first();
if ( !$user ) return redirect()->to('home'); //or wherever you want
$user->password = Hash::make($password);
$user->update(); //or $user->save();
//do we log the user directly or let them login and try their password for the first time ? if yes
Auth::login($user);
// If the user shouldn't reuse the token later, delete the token
DB::table('password_resets')->where('email', $user->email')->delete();
//redirect where we want according to whether they are logged in or not.
}
Don't forget to add routes
不要忘记添加路由
Route::get('password-reset', 'PasswordController@showForm'); //I did not create this controller. it simply displays a view with a form to take the email
Route::post('password-reset', 'PasswordController@sendPasswordResetToken');
Route::get('reset-password/{token}', 'PasswordController@showPasswordResetForm');
Route::post('reset-password/{token}', 'PasswordController@resetPassword');
Note: There might be typos or syntax errors because I did not test this and wrote it here directly from the top of my head. If you see an error/exception, don't panick, read the error and search google.
注意:可能有拼写错误或语法错误,因为我没有对此进行测试,而是直接从头开始写在这里。如果您看到错误/异常,请不要惊慌,阅读错误并搜索谷歌。