hiz77's avatar

How to Hash user input password when using Form Validation in Form Request( Laravel 5)

In my Controller class

public function postAccountCreate(postRequest $request, User $user) {

    $user->create($request->all());  

}

this single line of code does almost all the work by validating and then saving all the user form inputs to the users table when creating account for a user. However I couldn't figure out how and where to Hash the user password before saving it to the database table. Please help!

0 likes
13 replies
pstephan1187's avatar

A good way to handle that would to create a setter method on your eloquent model:

public function setPasswordAttribute($value){
    $this->attributes['password'] = bcrypt($value);
}

Anytime a password is assigned, it will be hashed.

16 likes
gemini_man93's avatar

@pstephan1187 thank you this is a great point. Could you please explain it ? because I am new to laravel and need to understand things, copy pasting is not enough, I want to understand it that how setPasswordAttribute will be call when I add new user or update existing one.

roulendz's avatar
Level 6

Put this in your User.php modeI

    public function setPasswordAttribute($password)
    {   
        $this->attributes['password'] = bcrypt($password);
    }
16 likes
hiz77's avatar

Thanks guys! it works :) am new for Laravel :)

devdurbs's avatar

I know this was a long time ago but for anyone coming across this, adding this method will prevent the built in Laravel password reset method from working. ResetsPasswords.php passes an encrypted password so the setter above will re-hash the new password.

5 likes
jamesfairhurst's avatar

Just had the same issue as @devdurbs, had a User::updating event which hashed the password automatically and was scratching my head why the password reset functionality wasn't working. Had to resort to putting the password hashing in the Controller.

1 like
redtagca's avatar

@devdurbs @james_fairhurst apparently its said you can get around that issue with the needRehash function:

if(Hash::needsRehash($password)) { $password = bcrypt($password); }

2 likes
Coldzer0's avatar

i add this input to my reser.blade.php

(</input type="hidden" name="bcrypt" value="HoHoHo"/>)

remove "/" and "(" , ")"

and then this to User.php model :D

so if the request not have "bcrypt" input then it will use $this->attributes['password'] = bcrypt($password);

else it will user $this->attributes['password'] = $password;

public function setPasswordAttribute( $password ) {

    if ( $password !== null ) {
        if ( is_null(request()->bcrypt) ) {
            $this->attributes['password'] = bcrypt($password);
        } else {
            $this->attributes['password'] = $password;
        }
    }
}
Waxben1's avatar

Okay @CodezerO so which means you check whether password is hashed or not in your reset.blade.php right ???

Xenonth's avatar

I know this is probably too late. But the problem with @roulendz answer is that it breaks the password reset functionality provded by laravel's scaffolding.

See issue here: https://laracasts.com/discuss/channels/general-discussion/laravel-5-password-reset-not-working

In Laravel's ResetsPasswords trait, the resetPassword method hashes the password for us before the setPasswordAttribute does its job.

// ResetsPasswords.php
protected function resetPassword($user, $password)
{
    // First round of hashing happens here.
    $user->password = Hash::make($password);

    $user->setRememberToken(Str::random(60));

    // Second round of hashing happens here.
    $user->save();

    ...
}

So to prevent this issue, all we need to do is to check whether or not we need to rehash the password.

// User.php
public function setPasswordAttribute($value)
{
    return $this->attributes['password'] = Hash::needsRehash($value) ? Hash::make($value) : $value;
}
7 likes

Please or to participate in this conversation.