我一直在网上搜索,但尚未找到解决以下问题的方法......
我们目前有一个使用Laravel开发的网站,其用户表是远程Microsoft SQL数据库。 config/auth.php
中的驱动程序已设置为"数据库"。除密码重置功能外,一切正常,我们收到以下错误:
UnexpectedValueException in PasswordBroker.php line 238: User must implement CanResetPassword interface.
根据我对Laravel的有限理解(这是我第一次使用Laravel),Eloquent驱动程序支持CanResetPassword功能,但是Laravel尚未在数据库用户提供程序中实现,因此错误。
所以我的问题是,有没有人有一个配置,他们有“数据库”的驱动程序,并实现了重置密码功能?我迄今看到的所有示例都与使用Eloquent模型有关,从我对Laravel的理解不是一个选项,因为在初始开发期间我们必须将驱动程序从Eloquent更改为数据库以使远程Microsoft SQL服务器在第一名。我担心,将Microsoft SQL数据库移动到本地数据库不是一种选择。
或者,如果有人实施了另一种用户使用电子邮件地址重置密码的方法,我会接受建议。
答案 0 :(得分:16)
要编写自己的密码重置逻辑,您仍然可以使用开箱即用的默认迁移,或者只创建自己的密码重置逻辑。最重要的部分是令牌。因为您正在重置密码,所以您需要做出几个决定:
在同一控制器中需要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
*/
}
第二部分,当用户点击链接时
/**
* 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');
}
显示包含2个输入的表单的页面
- 您想要的新密码password
或whateveer
- 新密码确认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.
}
不要忘记添加路线
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');
注意:可能存在拼写错误或语法错误,因为我没有对此进行测试,而是直接在我的脑海中写下来。如果您发现错误/异常,请不要惊慌失措,请阅读错误并搜索谷歌。
答案 1 :(得分:2)
只需添加@eddythedove所说的内容即可。
我使用Laravel创建令牌的方式,而不是EnableModelValidation="true"
:
str_random(60)
答案 2 :(得分:0)
如果在str_random
中发现错误,请确保先导入模块:
use Illuminate\Support\Str;
然后用Str::random (60)
进行呼叫。
答案 3 :(得分:0)
$key = config('app.key');
if (Str::startsWith($key, 'base64:')) {
$key = base64_decode(substr($key, 7));
}
$token = hash_hmac('sha256', Str::random(40), $key);
$dbToken = app(Hasher::class)->make($token);
DB::insert('password_resets', [
'email' => 'email@mail.com',
'token' => $dbToken,
]);
这应该适用于 Laravel 8