I'm using the Laravel 4 password reminder functionality, as described here: http://four.laravel.com/docs/security#password-reminders-and-reset. In order to generate the token, send the email and create de DB record in the password_reminder table, I use the standard code in my routes file :

Route::post('password/remind', function() {
  $credentials = array('email' => Input::get('email'));
  return Password::remind($credentials);
});

This code is suppose to send me back to my input form in case of any error (unknown email address for instance). Instead of that, I get a MethodNotAllowedHttpException. The reason is Laravel don't try to send me back to my form URL (which is /password/forgot): he tries to redirect me to /password/remind, in GET, and this route does not exist (of course) in my routes.php file.

I checked the code of the Illuminate\Auth\Reminders\PasswordBroker class, which is responsible of this redirection, and found out this method :

protected function makeErrorRedirect($reason = '')
{
  if ($reason != '') $reason = 'reminders.'.$reason;
  return $this->redirect->refresh()->with('error', true)->with('reason', $reason);
}

I replaced $this->redirect->refresh() by $this->redirect->back(), and everything is now working as excepted. But as I couldn't find any comment on this bug anywhere, I assume I'm doing something wrong… But I can't find what !

Here is my routes.php file:

Route::get('password/forgot', array('as' => 'forgot', 'uses' => 'SessionsController@forgot'));
Route::post('password/remind', function() {
    $credentials = array('email' => Input::get('email'));
    return Password::remind($credentials);
});
Route::get('password/reset/{token}', function($token) {
    return View::make('sessions.reset')->with('token', $token);
});
Route::post('password/reset/{token}', array('as' => 'reset', 'uses' => 'SessionsController@reset'));

my SessionsController relevant code:

class SessionsController extends BaseController {

    [...]

    public function forgot() {
        return View::make('sessions.forgot');
    }

    public function reset() {
        $credentials = array(
            'email' => Input::get('email'),
            'password' => Input::get('password'),
            'password_confirmation' => Input::get('password_confirmation')
        );

        Input::flash();

        return Password::reset($credentials, function($user, $password) {
            $user->password = Hash::make($password);            
            $user->save();
            return Redirect::to('home');
        });
    }

}

and finally my view code:

{{ Form::open(array('url' => 'password/remind', 'class' => 'form', 'role' => 'form', 'method'=>'post')) }}
    <div class="form-group">
        {{ Form::label('email', 'E-mail') }}
        {{ Form::text('email', '', array('autocomplete'=>'off', 'class' => 'form-control')) }}
    </div>
    {{ Form::submit("Envoyer", array("class"=>"btn btn-primary")) }}
{{ Form::close() }}
有帮助吗?

解决方案

If it is possible, I highly recommend you to upgrade to Laravel 4.1, because it comes with a more flexible (also easier to understand and to work with) solution for password remind/reset.

Check out this example with Laravel 4.1:

https://github.com/laracasts/Laravel-4.1-Password-Resets/blob/master/app/controllers/RemindersController.php

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top