Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use MD5 hashing for passwords in Laravel?

I'm porting over a legacy app into Laravel. The old app used MD5 to hash the passwords without a salt, so I need to replicate that within Laravel. For the record, we are changing the passwords to bcrypt with a salt, but it's not a simple process and requires a user login to do so - for the meantime I just need to get logins working with the legacy hashes.

I have followed this guide to convert Auth::hash to MD5: How to use SHA1 encryption instead of BCrypt in Laravel 4?

When I print out the password in plain text and the generated hash in my make method when registering an account:

public function make($value, array $options = array()) {
    echo $value.'<br>'.hash('md5', $value);
    exit;
    return hash('md5', $value);
}

I get the following:

123456
e10adc3949ba59abbe56e057f20f883e

Great, that's what I need. However, when that is saved to the database I get a different hash entirely. My guess is that Laravel is salting the password elsewhere, but I can't find where and how to override this.

My MD5Hasher.php file inside app/libraries:

<?php
class MD5Hasher implements Illuminate\Contracts\Hashing\Hasher {

    /**
     * Hash the given value.
     *
     * @param  string  $value
     * @return array   $options
     * @return string
     */
    public function make($value, array $options = array()) {
        return hash('md5', $value);
    }

    /**
     * Check the given plain value against a hash.
     *
     * @param  string  $value
     * @param  string  $hashedValue
     * @param  array   $options
     * @return bool
     */
    public function check($value, $hashedValue, array $options = array()) {
        return $this->make($value) === $hashedValue;
    }

    /**
     * Check if the given hash has been hashed using the given options.
     *
     * @param  string  $hashedValue
     * @param  array   $options
     * @return bool
     */
    public function needsRehash($hashedValue, array $options = array()) {
        return false;
    }

}

My MD5HashServiceProvider.php:

<?php
class MD5HashServiceProvider extends Illuminate\Support\ServiceProvider {

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register() {
        $this->app['hash'] = $this->app->share(function () {
            return new MD5Hasher();
        });

    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides() {
        return array('hash');
    }

}

My AuthController.php looks like the following:

<?php

namespace App\Http\Controllers\Auth;

use Hash;
use App\User;
use Validator;
use Mail;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;

class AuthController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Registration & Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users, as well as the
    | authentication of existing users. By default, this controller uses
    | a simple trait to add these behaviors. Why don't you explore it?
    |
    */

    use AuthenticatesAndRegistersUsers, ThrottlesLogins;

    //protected $redirectTo = '/account';

    /**
     * Create a new authentication controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest', ['except' => 'getLogout']);
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|confirmed|min:6',
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return User
     */
    protected function create(array $data)
    {
        $this->redirectTo = '/register/step-1';

        $user = User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);

        // email the user
        Mail::send('emails.register', ['user' => $user], function($message) use ($user)
        {
            $message->to($user->email, $user->name)->subject('Edexus - Welcome');
        });

        // email the admin
        Mail::send('emails.register-admin', ['user' => $user], function($message) use ($user)
        {
            $message->to('admins@***.com', 'Edexus')->subject('Edexus - New user sign up');
        });

        return $user;
    }
}
like image 648
Mike Avatar asked Nov 06 '15 08:11

Mike


1 Answers

Check out the password mutator in your User Model. It's hashing the password another time after hashing it in the controller.

My recommendation is hash the password once in your creating() and updating() model events, and remove it from the mutator and controller.

like image 84
Mina Abadir Avatar answered Sep 22 '22 07:09

Mina Abadir