Hasherとは、パスワードからHashの作成に使用される関数です。さて、Hashとはなんぞや?

例えば、パスワードをtesttestとします。これをHasherに与えると、
$2y$10$CE4R5SS6f5g4Rd0fgYRbneoeCOYbE0S2xfaYNC7i41CLysQ8TRUPO
のような文字列を生成します。これがHashです。

Hashは暗号化と異なり、非暗号化はできる機能はありません。つまり、
$2y$10$CE4R5SS6f5g4Rd0fgYRbneoeCOYbE0S2xfaYNC7i41CLysQ8TRUPO
から、もとのパスワードtesttestを解読できる機能はありません。

この特性を活かしてユーザー認証の機能のセキュリティを高めます。

まず会員登録時に入力したパスワードをHashした値をDBに保存します。そのままのテキストでは保存しません。そして、ログイン時に入力されたパスワードをHashして、DBに保存されたHashされたパスワードとマッチするかチェックします。マッチするなら認証OKです。

このHashする関数(Hasher)にはいろいろな種類があります。PHPでは、一昔前までは、

md5

を使用していました。md5は、必ず同じ値を返すので、Hashされたパスワードのマッチは、お互いの文字列を比較するだけです。

しかし、php5.5からは、よりセキュアな以下の関数の使用が薦められています。

password_hash

この関数が返すHashの値は、与えられる値が同じでも返す値が変わります。それゆえに、Hashされたパスワードのマッチにはもう1つの関数、

password_verify

を使用します。以下のように。


$password = 'testtest';

$hashed = password_hash($password, PASSWORD_DEFAULT);

$result = password_verify($password, $hashed);

echo $result ? '認証成功' : '認証失敗';

Laravelも基本的に同様な関数を使用しています。

BcryptHasher

さて、新規にLaravelを使用してプログラムを書くならまったくこれで問題ありません。しかし、既存のプログラムをLaravelに書き換えるとき、例えば、既存のプログラムがパスワードのHashにmd5を使用しているなら、DBに保存されているパスワードでは、LaravelのHasherでは誰もログインが不可能となってしまいます。

これに対応するには、LaravelのHasherを取り換える必要があります。HasherはLaravelではプログラムを通して1種類しか使用できない仕組みなので、HasherのProviderを作成して取り換えることになります。

まず、新規のHasherを作成します。


namespace App\Services;

class MD5Hasher implements \Illuminate\Contracts\Hashing\Hasher {

    public function make($value, array $options = [])
    {
        return md5($value);
    }

    public function check($value, $hashedValue, array $options = [])
    {
        return (md5($value) == $hashedValue);
    }

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

\Illuminate\Contracts\Hashing\Hasherで定められている型をもとに、必要な関数を定義します。

次にこのHasherを登録するサービスプロバイダーを作成します。


namespace App\Providers;

use Illuminate\Support\ServiceProvider;

use App\Services\MD5Hasher;

class MD5HasherServiceProvider extends ServiceProvider {

    protected $defer = true;

    public function register()
    {
        $this->app->singleton('hash', function() {
            return new MD5Hasher;
        });
    }

    public function provides()
    {
        return ['hash'];
    }
}

そして、config/app.phpを編集して、Hasherをサービスプロバイダーを入れ替えます。

...
   'providers' => [

        /*
         * Laravel Framework Service Providers...
         */
        ...
        // Illuminate\Hashing\HashServiceProvider::class, //コメントして
        App\Providers\MD5HasherServiceProvider::class,   //登録する
...

最後に、以下をコマンドラインで実行します。

composer dump-autoload

By khino