Mr.Happy
Mr.Happy

Reputation: 2647

Laravel 5 reset password form not submitting if password is less than 6 characters

I am trying to reset my password but not able rest password if password length is less then 6. I am validating password filed with min:4 validation but when I enter more then 4 character form is not submitting but when I tried with more then 6 it is working.

Any Idea what is wrong in my code.

Here is my HTML:

<div class="reset_password_container">
    <div class="reset_bg">
        <form class="form-horizontal" role="form" method="POST" action="{{ url('/password/reset') }}">
            <input type="hidden" name="_token" value="{{ csrf_token() }}">
            <input type="hidden" name="token" value="{{ $token }}">

            <div class="find_account_container">
                <div class="find_inner_logo">
                    <h5>{{ trans('messages.reset_password_form.reset_password') }}</h5>
                </div>
                <div class="find_form_dv">
                    <div class="reset_para_dv">
                        <p>{{ trans('messages.reset_password_form.text_1') }}</p>
                        <div class="reset_email_dv">
                            <p>{{ trans('messages.reset_password_form.email') }} <a href="javascript:void(0);">{{ $email }}</a></p>
                        </div>
                    </div>
                    <div class="reset_form_dv">
                        <input type="hidden" class="txt" name="ID" value="{{ $email }}">
                        <input type="password" class="txt" name="password" value="{{ old('password') }}" placeholder="{{ trans('messages.reset_password_form.password') }}">
                        <p class="error"></p>

                        <input type="password" class="txt" name="password_confirmation" value="{{ old('password_confirmation') }}" placeholder="{{ trans('messages.reset_password_form.password_confirmation') }}">
                        <p class="error">
                            @if ($errors->has('password'))
                                {{ $errors->first('password') }}
                            @endif
                        </p>
                    </div>
                </div>
            </div>
            <div class="reset_footer_bg">
                <div class="rest_btn_bg">
                    <button type="submit" class="btn btn-primary">{{ trans('messages.reset_password_form.confirm') }}</button>
                </div>
            </div>
        </form>
    </div>
</div>

PasswordController.php

<?php

namespace App\Http\Controllers\Auth;

use Illuminate\Http\Request;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Password;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Support\Facades\Input;
use Mail;
use DB;


class PasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Password Reset Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password reset requests
    | and uses a simple trait to include this behavior. You're free to
    | explore this trait and override any methods you wish to tweak.
    |
    */

    use ResetsPasswords;

    /**
     * Create a new password controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        //$this->middleware('guest');
    }

    /**
     * Get the post register / login redirect path.
     *
     * @return string
     */
    public function redirectPath()
    {
        if (property_exists($this, 'redirectPath')) {
            return $this->redirectPath;
        }

        return property_exists($this, 'redirectTo') ? $this->redirectTo : '/dashboard';
    }

    /**
     * Display the password reset view for the given token.
     *
     * @param  string  $token
     * @return \Illuminate\Http\Response
     */
    public function getReset($token = null, Request $request)
    {
        if (is_null($token)) {
            throw new NotFoundHttpException;
        } else {
            $userReset = DB::table('password_resets')->select('email')->where('token','=',$token)->get();
        }

        if (!empty($userReset)) {
            return view('auth.reset')->with('token', $token)->with('email', $userReset[0]->email);
        } else {
            return redirect('/');
        }

    }

    /**
     * Send a reset link to the given user.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function postEmail(Request $request)
    {
        //Input::get('ID') die;
        $this->validate($request, ['ID' => 'required|email']);

        // Pass data to reset password mail template
        view()->composer('emails.password', function($view) {
            $view->with([
                'Nickname'   => Input::get('nickname'),
            ]);
        });

        $response = Password::sendResetLink($request->only('ID'), function (Message $message) {
            $message->subject('비밀번호 재설정 안내');
            //$message->subject($this->getEmailSubject());
        });

        if ($response == "passwords.sent") {
            $html = '<div class="img_left_dv"><img src="resources/assets/front/images/suggestion_2.png" alt=""/></div>
            <div class="text_right_dv">
                <h3>'.Input::get('nickname').'</h3>
                <p><a href="javascript:void(0);">'.Input::get('ID').'</a> '.trans('messages.reset_password_popup.confirmation_message').'</p>
            </div>';
            echo $html;
        }
    }

    /**
     * Reset the given user's password.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function postReset(Request $request)
    {
        $this->validate($request, [
            'token' => 'required',
            'ID' => 'required|email',
            'password' => 'required|min:4|confirmed',
            'password_confirmation' => 'required|same:password|min:4'
        ]);

        $credentials = $request->only(
            'ID', 'password', 'password_confirmation', 'token'
        );

        $response = Password::reset($credentials, function ($user, $password) {
            $this->resetPassword($user, $password);
        });

        switch ($response) {
            case Password::PASSWORD_RESET:
                return redirect($this->redirectPath())->with('status', trans($response));

            default:
                return redirect()->back()
                            ->withInput($request->only('ID'))
                            ->withErrors(['ID' => trans($response)]);
        }
    }
}

Upvotes: 1

Views: 2181

Answers (4)

Armin
Armin

Reputation: 2562

You can use this gist to solve the issue. You have to create a new service provider which uses your custom password broker manager. When every thing is set up all you have to do is add your new service provider to your config\app.php :

'providers' => [
     ...
     // path to your PasswordResetServiceProvider
     App\Auth\PasswordResetServiceProvider::class 
 ]

Upvotes: 0

im3r3k
im3r3k

Reputation: 503

I noticed the same issue in Laravel 5.2. The reset password form requires a password of six or more characters, and it is set that way in two places.

1. PasswordBroker Class vendor/laravel/framework/src/Illuminate/Auth/Passwords/PasswordBroker.php:validatePasswordWithDefaults()

    protected function validatePasswordWithDefaults(array $credentials)                                                      
{   
    list($password, $confirm) = [
        $credentials['password'],
        $credentials['password_confirmation'],
    ];

    return $password === $confirm && mb_strlen($password) >= 6;
}

and

2. ResetsPasswords Trait vendor/laravel/framework/src/Illuminate/Foundation/Auth/ResetsPasswords.php:getResetValidationRules()

    protected function getResetValidationRules()
{   
    return [
        'token' => 'required',
        'email' => 'required|email',
        'password' => 'required|confirmed|min:6',
    ];  
}   

It is easy to override the getResetValidationRules() trait method in your app/Http/Controllers/Auth/PasswordController.php by implementing your own reset() and getResetValidationRules() methods.

However, in order to call your own PasswordBroker.php:validatePasswordWithDefaults() method it looks like it would require extending the PasswordBroker and PasswordBrokerManager and since that is initialized by the vendor/laravel/framework/src/Illuminate/Auth/Passwords/PasswordResetServiceProvider.php you will need to extend that as well. When all is done you can initialize your new "CustomPasswordResetServiceProvider" in Laravel's service container just as ResetPasswordServiceProvider is.

Upvotes: 0

Ankit Sompura
Ankit Sompura

Reputation: 763

Please try below function:

By default, the Password::reset method will verify that the passwords match and are >= six characters. You may customize these rules using the Password::validator method, which accepts a Closure. Within this Closure, you may do any password validation you wish. Note that you are not required to verify that the passwords match, as this will be done automatically by the framework.

Password::validator(function($credentials)
{
    return strlen($credentials['password']) >= 4;
});

Upvotes: 1

Niraj Shah
Niraj Shah

Reputation: 15457

Your validation rule in postReset is superseded by getResetValidationRules function in Illuminate\Foundation\Auth\ResetsPasswords.php:

protected function getResetValidationRules()
{
    return [
        'token' => 'required',
        'email' => 'required|email',
        'password' => 'required|confirmed|min:6',
    ];
}

To fix this, you need to:

  • Add the getResetValidationRules function to your PasswordController.php file.
  • Remove the postReset function you created (this is just duplicating code that already exists)
  • Rename your ID form field to email and let Laravel handle the rest

So, you PasswordController.php should just contain:

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;

class PasswordController extends Controller
{

    use ResetsPasswords;

    /**
     * Create a new password controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    public function getResetValidationRules()
    {
        return [
            'token' => 'required',
            'email' => 'required|email',
            'password' => 'required|confirmed|min:4',
        ];
    }
}

Upvotes: 0

Related Questions