Reputation: 4526
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>
Upvotes: 25
Views: 91896
Reputation: 21
Validation rules for Laravel 8.*
use default available validation rules:
[
'current_password' => ['required', 'string', 'current_password'],
'password' => ['required', 'string', 'min:4', 'confirmed']
]
current_password based on Laravel Document check parameter to be equaled to authenticated user password
confirmed based on Laravel Document check parameter to equaled with new parameter named:
{parameter}_confirmation
Upvotes: 2
Reputation: 1763
Validation rules for laravel 8.*
Default
'current_password' => 'required|current_password',
'password' => 'required|min:8|confirmed',
Custom
php artisan make:rule MatchOldPassword
//inside MatchOldPassword
public function passes($attribute, $value)
{
return Hash::check($value, auth()->user()->password);
}
'current_password' => ['required', new MatchOldPassword()],
'password' => 'required|min:8|confirmed',
Upvotes: 1
Reputation: 4804
In Laravel 8.x
you can use this method in UserController.php
:
public function ChangePasswordStore(Request $request, $user_id)
{
$user = User::findOrFail($user_id);
$request->validate([
'password' => 'required|confirmed|string|min:8',
'current_password' => ['required', function ($attr, $password, $validation) use ($user) {
if (!\Hash::check($password, $user->password)) {
return $validation(__('The current password is incorrect.'));
}
}],
]);
User::where('id', $user_id)->update([
'password' => Hash::make($request->input('password')),
]);
return redirect()->back();
}
In web.php
:
Route::post('/user/{user_id}/changepassword', [
App\Http\Controllers\Admin\UserController::class,
'changepasswordStore'
])->name('users.changepassword.store');
Upvotes: -1
Reputation: 109
You can add confirmed
as it's to confirm old password.
And 'required|confirmed'
you change to 'required|same:password'
to compare password
and password confirmation
'old_password' => 'required|confirmed',
'password' => 'required|min:4',
'password_confirmation' => 'required|same:password'
Good luck!
Upvotes: -1
Reputation: 689
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',
Upvotes: 16
Reputation: 1922
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
For example:
if(request(input)){
$data += ['input' => request(input)];
}
For example:
Auth::user()->account->update($data);
Upvotes: 4
Reputation: 5853
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
Upvotes: 34
Reputation: 4224
A complete function which will check everything. You just need to send old_password
, new_password
and confirm_password
.
public function changePassword(Request $request) {
try {
$valid = validator($request->only('old_password', 'new_password', 'confirm_password'), [
'old_password' => 'required|string|min:6',
'new_password' => 'required|string|min:6|different:old_password',
'confirm_password' => 'required_with:new_password|same:new_password|string|min:6',
], [
'confirm_password.required_with' => 'Confirm password is required.'
]);
if ($valid->fails()) {
return response()->json([
'errors' => $valid->errors(),
'message' => 'Faild to update password.',
'status' => false
], 200);
}
// Hash::check("param1", "param2")
// param1 - user password that has been entered on the form
// param2 - old password hash stored in database
if (Hash::check($request->get('old_password'), Auth::user()->password)) {
$user = User::find(Auth::user()->id);
$user->password = (new BcryptHasher)->make($request->get('new_password'));
if ($user->save()) {
return response()->json([
'data' => [],
'message' => 'Your password has been updated',
'status' => true
], 200);
}
} else {
return response()->json([
'errors' => [],
'message' => 'Wrong password entered.',
'status' => false
], 200);
}
} catch (Exception $e) {
return response()->json([
'errors' => $e->getMessage(),
'message' => 'Please try again',
'status' => false
], 200);
}
}
Upvotes: 0
Reputation: 10044
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,
]);
Upvotes: 5
Reputation: 5833
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'
Upvotes: 66