web-dev-qa-db-ja.com

データベースユーザープロバイダーを使用する場合、Laravel=でパスワードリセットメソッドを作成する方法

私はインターネットを検索していますが、次の問題の解決策をまだ見つけていません...

現在、Laravelを使用して開発されたWebサイトがあります。これはユーザーテーブルはリモートMicrosoft SQLデータベースです。_config/auth.php_のドライバーは "database"に設定されています。パスワードリセット機能。次のエラーが表示されます。

_UnexpectedValueException in PasswordBroker.php line 238: User must implement CanResetPassword interface.
_

Laravel(これはLaravelでの最初の経験です)の私の限られた理解から、EloquentドライバーはCanResetPassword機能をサポートしていますが、これはLaravelによってデータベースユーザープロバイダーに実装されていません。したがって、エラー。

したがって、私の質問は、「データベース」へのドライバーを持ち、パスワードのリセット機能を実装した構成を持っている人はいますか?これまで見てきたすべての例は、Eloquentモデルの使用に関連しています。これは、Laravelの私の理解から、最初の開発中にドライバーをEloquentからデータベースに変更しなければならなかったため、オプションではありませんMicrosoft SQLデータベースをローカルデータベースに移動することは、私が恐れているオプションではありません。

あるいは、ユーザーが電子メールアドレスを使用してパスワードをリセットする別の方法を実装している場合は、提案を受け付けます。

10
short_coder

独自のパスワードリセットロジックを作成するには、そのまま使用できるデフォルトの移行を使用するか、単純に作成します。最も重要な部分はトークンです。自分でパスワードをリセットしているため、次の2つの決定を下す必要があります。

  • トークンの有効期限は切れますか?
  • ユーザーは同じトークンを複数回使用できますか?

同じコントローラーに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または必要なもの-新しいパスワードの確認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');

:私はこれをテストせず、頭の上から直接ここに書いたので、タイプミスや構文エラーがあるかもしれません。エラー/例外が表示された場合は、パニックしないで、エラーを読んでGoogleを検索してください。

18
EddyTheDove