Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate current, new, and new password confirmation in Laravel 5?

I have created the password route, view and method in UserController@getProfilePassword and UserController@postProfilePassword

At the moment, if I fill out the new_password field, it gets hashed and submitted to the database correctly, then I can login with the new password.

But I need to be able to validate the new_password and new_password_confirm to make sure they're the same and validate the user's current password as well.

How can I do that?

EDIT: I added $this->validate to the method, but now I keep getting the error The password confirmation confirmation does not match. even though they do match as I am using a simple password. Also I think I need to check against the current password manually as validator won't do it for me.

public function getProfilePassword(Request $request) {
    return view('profile/password', ['user' => Auth::user()]);
}

public function postProfilePassword(Request $request) {
    $user = Auth::user();

    $this->validate($request, [
        'old_password'          => 'required',
        'password'              => 'required|min:4',
        'password_confirmation' => 'required|confirmed'
    ]);

    $user->password = Hash::make(Input::get('new_password'));
    $user->save();
}

And this is the view

<form action="{{ route('profile/updatepassword') }}" method="post" enctype="multipart/form-data">
    <div class="form-group">
          <label for="name">Current Password</label>
          <input type="password" name="old_password" class="form-control" id="old_password">
    </div>
    <div class="form-group">
          <label for="name">Password</label>
          <input type="password" name="password" class="form-control" id="password">
    </div>
    <div class="form-group">
          <label for="name">New Password</label>
          <input type="password" name="password_confirmation" class="form-control" id="password_confirmation">
    </div>
    <button type="submit" class="btn btn-primary">Change Password</button>
    <input type="hidden" value="{{ Session::token() }}" name="_token">
 </form>
like image 802
Halnex Avatar asked Jun 01 '16 00:06

Halnex


People also ask

What is my new password and confirm password laravel?

In your form. blade, ensure that the password input field has a name attribute of name="password" -> it has to be password , Also, add an attribute of name="password_confirmation" to the Confirm Password text input box, and it will work.

What is confirmed in laravel validation?

By default, Laravel 'confirmed' validator adds the error message to the original field and not to the field which usually contains the confirmed value.


5 Answers

There's a Hash::check() function which allows you to check whether the old password entered by user is correct or not.

usage

if (Hash::check("param1", "param2")) {
 //add logic here
}

param1 - user password that has been entered on the form
param2 - old password hash stored in database

it will return true if old password has been entered correctly and you can add your logic accordingly

for new_password and new_confirm_password to be same, you can add your validation in form request like

'new_password' => 'required',
'new_confirm_password' => 'required|same:new_password'
like image 174
Sid Avatar answered Oct 05 '22 20:10

Sid


If you only need the functionality of a custom rule once throughout your application, you may use a Closure instead of a rule object. The Closure receives the attribute's name, the attribute's value, and a $fail callback that should be called if validation fails

$request->validate([
    'new_password' => 'required|confirmed|min:4',
    'current_password' => ['required', function ($attribute, $value, $fail) use ($user) {
        if (!\Hash::check($value, $user->password)) {
            return $fail(__('The current password is incorrect.'));
        }
    }],
]);

https://laravel.com/docs/5.6/validation#using-closures

like image 43
Steve Avatar answered Oct 05 '22 19:10

Steve


In Laravel 6 there is a new rule called password ,according to docs

The field under validation must match the authenticated user's password. You may specify an authentication guard using the rule's first parameter:
'password' => 'password:api'

so the validation rules can be as simple as :

'current_password' => 'required|password',
'password' => 'required|string|min:8|confirmed',
like image 23
Arash Moosapour Avatar answered Oct 05 '22 19:10

Arash Moosapour


You can do this by creating a custom validation rule (for this example I'm using current_password and new_password as the input names).

Put this in AppServiceProvider::boot():

Validator::extend('current_password', function ($attribute, $value, $parameters, $validator) {
    $user = User::find($parameters[0]);

    return $user && Hash::check($value, $user->password);
});

Now you can use the following in your controller:

$user = auth()->user(); // or pass an actual user here

$this->validate($request, [
    'current_password' => 'required_with:new_password|current_password,'.$user->id,
]);
like image 38
kjdion84 Avatar answered Oct 05 '22 19:10

kjdion84


Using laravel 5.8/6.0, here is what i do(without much additional code)

Step 1: Validate

    $data = request()->validate([
        'firstname' => ['required', 'string', 'max:255'],
        'lastname' => ['required', 'string', 'max:255'],
        'username' => ['bail', 'nullable', 'string', 'max:255', 'unique:users'],
        'email' => ['bail', 'nullable', 'string', 'email:rfc,strict,dns,spoof,filter', 'max:255', 'unique:users'],
        'new_password' => ['nullable', 'string', 'min:8'],
        'confirm_new_password' => ['nullable', 'required_with:new_password', 'same:new_password'],
        'current_password' => ['required', function ($attribute, $value, $fail) {
            if (!\Hash::check($value, Auth::user()->password)) {
                return $fail(__('The current password is incorrect.'));
            }
        }]
    ]);

Step 2: If validation is passed

  1. Create array , checking each input value (but not the ones with the required tag in validation) for presence or null OR do something that you want.

For example:

if(request(input)){
    $data += ['input' => request(input)];
}
  1. Update database using the created array

For example:

Auth::user()->account->update($data);
like image 24
MR_AMDEV Avatar answered Oct 05 '22 19:10

MR_AMDEV