How can I change Md5 Passwords to Bcrypt in Laravel 5.4?

Published 7 months ago by sufuninja

I have tried several solutions online but nothing has worked.

I am pretty lost.

Best Answer (As Selected By sufuninja)
jaydeluca

@sufuninja to add more context to my previous answer and to go along with what @Snapey just said, I went to the file Snapey referenced (vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php), copied the login function from it, pasted it into app/Http/Controllers/Auth/LoginController.php and made the following modifications there.


/**
 * Overwrite default login method to help migrate viewers to using
 * bcrypt encrypted passwords
 */
public function login(Request $request)
{
    $this->validateLogin($request);

    // If the class is using the ThrottlesLogins trait, we can automatically throttle
    // the login attempts for this application. We'll key this by the username and
    // the IP address of the client making these requests into this application.
    if ($this->hasTooManyLoginAttempts($request)) {
        $this->fireLockoutEvent($request);

        return $this->sendLockoutResponse($request);
    }

    // check if account logging in for first time
    // check against old md5 password, if correct, create bcrypted updated pw
    $user = User::where('email', $request->input('email'))->first();
    if (!$user->password_updated) {
        if ($this->sqlPassword($request->input('password')) === $user->old_password) {
            $user->password = bcrypt($request->input('password'));
            $user->password_updated = 1;
            $user->save();
        } else {
            return $this->sendLoginResponse($request);
        }
    }

    if ($this->attemptLogin($request)) {
        return $this->sendLoginResponse($request);
    }

    // If the login attempt was unsuccessful we will increment the number of attempts
    // to login and redirect the user back to the login form. Of course, when this
    // user surpasses their maximum number of attempts they will get locked out.
    $this->incrementLoginAttempts($request);

    return $this->sendFailedLoginResponse($request);
}
EmilMoe

What do you mean? You can't convert a hash to another hash

alexhiggins

You can't decrypt md5

EmilMoe

@alexhiggins sure you can, or bruteforce with rainbow tables, but not really a reliable solution.

@sufuninja if understand you correct you need to bcrypt the origin value. Normally you would ask every user to change password.

alexhiggins

Yeap - there's sites too, does not mean it's viable for what he's wanting to do

sufuninja

Sorry, let me clarify.

I have a database with Md5 hashed passwords.

When a user logs in, I would like to auth first with Md5 (if old password) and upon success, rehash using bcrypt and save the new password.

EmilMoe

You mean this?

$user = User::where('username' => $username)->where('md5_password', md5($password)->firstOrFail();

$user->update(['bcrypt_password' => Hash::make($password)]);
sufuninja

Where would something like that go? I using laravel's pre-built authentication controllers.

EmilMoe

There's a login event, maybe you can catch the password there: https://laravel.com/docs/5.4/authentication#events

jlrdw
jlrdw
7 months ago (202,050 XP)

@Snapey read this discussion, very interesting indeed. OP, it's been discussed and worked out, one by one when the user logs in. Please search forum.

jaydeluca

This is how I handled it:

I created a two new rows in the database, old_password, and password_updated (default false). I then wrote a seeder to copy the existing password into the old_password field, and then added this to my LoginControler

// check if account logging in for first time
// check against old md5 password, if correct, create bcrypted updated pw
$user = User::where('email', $request->input('email'))->first();
if (!$user->password_updated) {
    if ($this->sqlPassword($request->input('password')) === $user->old_password) {
        $user->password = bcrypt($request->input('password'));
        $user->password_updated = 1;
        $user->save();
    } else {
        return $this->sendLoginResponse($request);
    }
}
jlrdw
jlrdw
7 months ago (202,050 XP)

@jaydeluca great answer, something similar here https://laracasts.com/discuss/channels/laravel/md5-to-laravel-passwords

My point was it took me only 3 seconds to search.

But I have bookmarked your answer, neat code.

sufuninja

Thank all of you for the help. I have tried a few different approaches but every one seems to be missing just one step. I'll be back on it tomorrow.

@jlrdw , I read that thread but failed to find App\Auth\AuthController. I wouldn't have reached out if my searches lead me to success.

Thanks again.

Snapey
Snapey
7 months ago (770,895 XP)

In 5.4 the boiler plate auth controllers have been split up a bit.

The one you are interested in is Auth/LoginController

This uses the AuthenticatesUsers trait which can be found at vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php

Find the code you need to extend in there and duplicate it to your controller. It will then overload the trait method and you can edit it within your own app area

jaydeluca

@sufuninja to add more context to my previous answer and to go along with what @Snapey just said, I went to the file Snapey referenced (vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php), copied the login function from it, pasted it into app/Http/Controllers/Auth/LoginController.php and made the following modifications there.


/**
 * Overwrite default login method to help migrate viewers to using
 * bcrypt encrypted passwords
 */
public function login(Request $request)
{
    $this->validateLogin($request);

    // If the class is using the ThrottlesLogins trait, we can automatically throttle
    // the login attempts for this application. We'll key this by the username and
    // the IP address of the client making these requests into this application.
    if ($this->hasTooManyLoginAttempts($request)) {
        $this->fireLockoutEvent($request);

        return $this->sendLockoutResponse($request);
    }

    // check if account logging in for first time
    // check against old md5 password, if correct, create bcrypted updated pw
    $user = User::where('email', $request->input('email'))->first();
    if (!$user->password_updated) {
        if ($this->sqlPassword($request->input('password')) === $user->old_password) {
            $user->password = bcrypt($request->input('password'));
            $user->password_updated = 1;
            $user->save();
        } else {
            return $this->sendLoginResponse($request);
        }
    }

    if ($this->attemptLogin($request)) {
        return $this->sendLoginResponse($request);
    }

    // If the login attempt was unsuccessful we will increment the number of attempts
    // to login and redirect the user back to the login form. Of course, when this
    // user surpasses their maximum number of attempts they will get locked out.
    $this->incrementLoginAttempts($request);

    return $this->sendFailedLoginResponse($request);
}
sufuninja

Thank all of you for your help and patience.

This is much more straight forward and simple than trying to make a custom provider, edit autoload, edit composer.json and on and on.

Please sign in or create an account to participate in this conversation.