PHP
laravel

[Larabel 5.6] 入力した文字列(平文)と Hash::make() で生成されたハッシュ値を比較する方法

環境

CentOS: 7.4
PHP: 7.2
Laravel: 5.6

やりたいこと

こんな感じでパスワード更新機能を実装したい。
DBにはHash::make()でハッシュ化されたパスワードが登録済み。

パスワード更新.PNG

Hash::check()を使う

ポストされた平文のパスワードと、DBに保存されているハッシュ化されたパスワードを比較したいときはHash::check()を使います。

Hash::check('plain-text', $hashedPassword)

例えば、コントローラー内ではこんな感じ。

public function update(Request $request, $id)  // パスワード更新のアクション
{
    $user       = User::find($id);
    $currentPwd = $request['current-password']

    if (Hash::check($currentPwd, $user->password)) {
        // 一致したときの処理
    } else {
        // 一致しなかったときの処理
    }
}

Hash::make()は毎回違うハッシュ値を返す

Hash::make()は、たとえ同じ値をハッシュ化したとしても、毎回違うハッシュ値になります。
これはハッシュ化される際に毎回違うソルトが付与されているからです。

Hash::make('123456789')
// 1回目 -> "$2y$10$Mwpc4sWmavJejMja/cLVaOcr51OuOdrmyZRLg2KCitqEgvAGwnvkO"

Hash::make('123456789')
// 2回目 -> "$2y$10$v9jdbMmI2N4x4/Osk.jDrOQKgTAEAKwKwfDtdjkoOcjP4bZ57Fqte"

なので、入力された現パスワードをHash::make()でハッシュ化した値とDBに保存されているハッシュ化されたパスワードを比較しても一致することはないんですね。

public function update(Request $request, $id)
{
    $user = User::find($id);
    $hash = Hash::make($request['current-password'])

    dd($hash == $user->password)  // -> FALSE
}

「ハッシュは同じ値に対しては同じハッシュ値を返す」と聞いていたので少し勘違いしてしまったのですが、Hash::make()はパスワード保存用にセキュリティを強化されたメソッドのようなので、単純なハッシュ関数とは違うんですね。なるほど。

参考

https://readouble.com/laravel/5.6/ja/hashing.html