12
votes

I am trying to validate a password field only if it is present. I want to allow someone to edit a user and they may or may not want to change the users password. So I thought I could this using Laravels validation rules, specifically the 'sometimes' rule. I have this set of rules:

$this->validate($request, [
    'password' => 'sometimes|required|min:8',
]);

This is simplified for the example, there will usually be other rules for other fields and stricter rules for the password. I expect this to only apply the min:8 rule if the password field is present in the passed data, but if I leave the password field empty I get a validation error saying the password field is required.

I'm not sure what I'm not understanding in the docs. Do I need to manually remove the password field before validation if it is the form input was submitted empty like this?

$data = $request->all();

if ('' === $data['password']) {
    unset($data['password'])
}

...and then pass the array into the validator. I think this makes sense but I could do with some confirmation that I'm understanding it correctly. Thanks in advance.

7
From the docs, that's what i understand. So, basically you are good to go unless anyone tells otherwise.Nabin Kunwar
It also seems that if you remove the required rule, it works fine like this: 'sometimes|min:8.....', but the docs don't really make this clear.Steven1978
Yup. that's what i thought first, then checked the docs again. :DNabin Kunwar
I saw a comment saying to do that so I did, then the comment vanished, was that you?Steven1978
yup. that was me. anyway glad could help.Nabin Kunwar

7 Answers

11
votes

Docs don't make it clear, But removing required makes it work.

$this->validate($request, [
    'password' => 'sometimes|min:8',
]);
15
votes

I think we should tell laravel If password is not empty put the rules otherwise do nothing.

$this->validate($request, [
  'password' => $request->password != null ?'sometimes|required|min:8': ''
]);
7
votes

"I am trying to validate a password field only if it is present."

To do this, you can use the "nullable" rule within the validation system.

For example:

$this->validate($request, [
    'password' => 'sometimes|nullable|min:8',
]);

For more information take a look at https://laravel.com/docs/5.6/validation section under "A Note On Optional Fields"

3
votes

I think it's generally safer to allow the user to change its password only if he can provided the old one.

Allowing the connected user to alter his password without providing the old one can be a security issue.

This is generally how I allow user password change with Laravel:

 $this->validate($request, [
            'user.old_password' => [],
            'user.password' => [
                'required_with:user.old_password',
                'min:6',
                'confirmed',
                'regex:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*([-+_!@#$%^&*.,;?])).+$/',
                'different:user.old_password'
            ],
            'user.password_confirmation' => ['required_with:user.password'],
        ]);

This don't validate the old password as we don't care, the database will check it for us, but I validate the new password only if the old one is provided.

2
votes

In edit mode you fill password field by for example "********" and in update mode validate like this

$this->validate($request, [
    'password' => 'required|min:8',
]);

and in controller check $data['password']='********' find old password and

$data['password']='old password in db'

and $data['password']!='********' update pssword

2
votes

As an option to the selected answer, you can use:

    $this->validate($request, [
       'password' => 'nullable|min:8',
    ]);
-1
votes

Laravel sometimes validation rule and their function:

accepted The field under validation must be yes, on, 1, or true. This is useful for validating "Terms of Service" acceptance.

active_url The field under validation must have a valid A or AAAA record according to the dns_get_record PHP function.

after:date The field under validation must be a value after a given date. The dates will be passed into the strtotime PHP function: 'start_date' => 'required|date|after:tomorrow' Instead of passing a date string to be evaluated by strtotime, you may specify another field to compare against the date: 'finish_date' => 'required|date|after:start_date'

after_or_equal:date The field under validation must be a value after or equal to the given date. For more information, see the after rule.

alpha The field under validation must be entirely alphabetic characters.