Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 6 Use a custom Hasher during migration from CakePHP 2.x

Tags:

laravel

lumen

We are migrating applications from CakePHP 2.X but we need to implement our mobile API's before the migration. I have followed all the items I could find but they all seem to be for v5 or less. No matter what I do Hash::make() still results in a Bcrypt password.

I really want to 2 birds one stone with having this allow sha1() login and update to Bcrypt upon login but we havent implemented on CakePHP 2.x successfully. So I need to get the Hasher working or a workaround. I know I can just Hash manually in the model but that doesnt allow Auth to work.

Any help would be appreciated

app.php config file

Illuminate\Foundation\Providers\FoundationServiceProvider::class,
//Illuminate\Hashing\HashServiceProvider::class,
App\Providers\CustomHashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,

CustomHashServiceProvider.php

    <?php
namespace App\Providers;

use Illuminate\Hashing\HashServiceProvider;
use App\Libs\CustomHash\CustomHasher as CustomHasher;

class CustomHashServiceProvider extends HashServiceProvider
{
    public function register()
    {
        $this->app->singleton('hash', function () {
            return new CustomHasher;
        });
    }
}

CustomHasher.php

<?php

namespace App\Lib\CustomHash;

use Illuminate\Contracts\Hashing\Hasher as HasherContract;

class CustomHasher implements HasherContract {

    /**
     * Hash the given value.
     *
     * @param  string  $value
     * @return array   $options
     * @return string
     */
    public function make($value, array $options = array()) {
        //I have custom encoding / encryption here//
        //Define your custom hashing logic here//
        return sha1(env('SEC_SALT').$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;
    }

    public function info($hashedValue): array {
        return $hashedValue;
    }
}

UPDATE I refactored based on @Mdexp answer to this .... but I found out the Configs are ignored unless added in app.php on Lumen

New app.php

/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\Sha1HashServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,

Sha1HashServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class Sha1HashServiceProvider extends ServiceProvider {

    public function register() {
        //
    }

    public function boot() {
        $this->app->make('hash')->extend('sha1', function () {
            // Just create the driver instance of the class you created in the step 1
            return new \App\Lib\Sha1Hash\Sha1Hasher;
        });
    }
}

Sha1Hasher.php

<?php

namespace App\Lib\Sha1Hash;

use Illuminate\Hashing\AbstractHasher;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use RuntimeException;

class Sha1Hasher extends AbstractHasher implements HasherContract {

    public function __construct(array $options = []) {

    }

    public function make($value, array $options = []) {
        $hash = sha1(env('SEC_SALT').$value);
        if ($hash === false) {
            throw new RuntimeException('Sha1 hashing not supported.');
        }
        return $hash;
    }

    public function check($value, $hashedValue, array $options = []) {

        return ($this->make($value) == $hashedValue)?true:false;
    }

    public function needsRehash($hashedValue, array $options = array()): bool {
        return false;
    }

}
like image 922
Ehask Avatar asked Dec 14 '25 04:12

Ehask


1 Answers

I would use the default HashServiceProvider and register a new driver into it. It would also make the switch back from sha1 to bcrypt even quicker once you completed the transitioning phase.

1) You have have to create a class which extends the Illuminate\Hashing\AbstractHasher or at least implements the Illuminate\Contracts\Hashing\Hasher. Take a look at the current Bcrypt driver implementation as a reference on GitHub. The CustomHasher class you provided should work just fine as a driver, I would just rename it to avoid confusion with naming.

2) Now you can register the hash drivers in a service provider like:

public function boot()
{
    $this->app->make('hash')->extend('sha1', function () {
        // Just create the driver instance of the class you created in the step 1
        return new YourCustomSha1Hasher();
    });
}

3) Then in your config/hashing.php file, set the driver to 'sha1' (must be equal to the first parameter of the extend function call.

4) It should work straight out of the box, and to choose a different hashing driver, just change the config/hashing.php configuration file with the driver that you want to use for hashing.

Note: the whole code hasn't been tested, but I looked through the source code to come up with this solution that should work. Just comment anything isn't working as expected so I can fix my answer.

like image 69
mdexp Avatar answered Dec 15 '25 22:12

mdexp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!