【Laravel】認証用のパスワードハッシュクラスの作成、登録、参照方法

 Laravel のパスワードはデフォルトでは Hash ファサード(\Hash や \Illuminate\Support\Facades\Hash の呼び出し先)で管理されています。
ハッシュ 6.x Laravel
 例えば \Hash;;make(‘パスワード平文’) でパスワードが作れます。しかし時には認証機能を持つ範囲によって複数のハッシュアルゴリズムを使い分けることがあります(そういう時もあります)。こうなると全てを \Hash で賄うのは難しくなります。認証機能の定義を呼び出して、使うハッシュアルゴリズムをデフォルトとは違う何かしらである、と登録する必要があり、その登録したハッシュアルゴリズムを認証機能から呼び出す必要があります。
 登録は Laravel のサービスコンテナと設定機能を使うのがベターです。ログイン処理を始めとした認証処理を都度オーバーライドすることでもできなくはないですが、Laravel のソースコードを解読する必要がある上に断片的なコードが増えて後から読み返しにくくなります。
 例として平文パスワードのハッシュアルゴリズムを登録します。これを行うためにはハッシュアルゴリズムクラスとその登録が必要です。
 ハッシュアルゴリズムは次です。

<?php

namespace App;

use Illuminate\Contracts\Hashing\Hasher as HasherContract;
// ハッシュアルゴリズムクラスはインターフェースである Illuminate\Contracts\Hashing\Hasher を満たす必要があります。

/**
 * ハッシュ処理時に平文を扱うための Hasher です。
 * Laravel の命名に従って Hasher としておりますが、その内容は PasswordHasher と冠詞を増やしても良い程にパスワード特化です。
 */
class PlainPasswordHasher implements HasherContract
{
    /**
     * ハッシュに関する情報を返すことが期待されるメソッドです
     * 他 Hasher では password_get_info 関数相当の動作が主になっています。
     * @see https://www.php.net/manual/ja/function.password-get-info.php
     * @param  string     $hashedValue
     * @return array|void
     */
    public function info($hashedValue)
    {
        return [
            'msg' => 'ハッシュ化はされていません',
        ];
    }

    /**
     * ハッシュ値を作るメソッドです。
     * @param  string      $value
     * @param  array       $options
     * @return string|void
     */
    public function make($value, array $options = [])
    {
        // 平文なのでそのまま返します。
        return $value;
    }

    /**
     * 与えられた平文値とハッシュされた値が同じかチェックします。
     * 他 Hasher では password_verify 関数が主に使われています
     * @see https://www.php.net/manual/ja/function.password-verify.php
     * @param  string    $value
     * @param  string    $hashedValue
     * @param  array     $options
     * @return bool|void
     */
    public function check($value, $hashedValue, array $options = [])
    {
        return $value === $hashedValue;
    }

    /**
     * 与えられたパスワードハッシュ値とオプションからパスワードハッシュを再計算する必要があるか否かの bool を返します。
     * ここでは平文なので常に false です。
     * @param  string $hashedValue
     * @param  array  $options
     * @return bool
     */
    public function needsRehash($hashedValue, array $options = [])
    {
        return false;
    }
}

 登録例は次です。登録時にはどの認証プロバイダークラスでどのハッシャークラスを使うか、どの認証モデルクラスでどの認証プロバイダクラスを使うかを定められます。

// app/Providers/AuthServiceProvider.php
class AuthServiceProvider extends ServiceProvider
{
    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot(): void
    {
        $this->registerPolicies();
        // /config/auth.php 内で eloquent とプロバイダーを指定された場合、
        // 平文パスワードの Hasher でパスワードの暗号化、認証処理を行います。
        Auth::provider('eloquent', function ($app, array $config) {
            return new EloquentUserProvider(new PlainPasswordHasher(), $config['model']);
        });
    }
}
// config/auth.php
// 省略
    'guards' => [
        'web' => [
            'driver'   => 'session',// Illuminate\Auth\SssionGuard を使用
            'provider' => 'users',
        ],
        // 他ガードは省略
    ],
    'providers' => [
        'users' => [
            'driver' => 'eloquent', // Illuminate\Auth\EloquentUserProvider を使用
            'model'  => App\Models\Eloquents\User::class, // 認証機能を持たせるユーザのテーブルを持つ Eloquent クラス
        ],
        // 他プロバイダは省略
    ],
// 省略

 上述のコードで任意の認証用のハッシュアルゴリズムを Laravel で使えます。特別なハッシュアルゴリズムで作られたデータベースを引き継ぐときなどに便利です。
 認証するのみでなく新たにパスワードをハッシュ化して生成する必要もあり、それは次でできます。

// app\Models\Eloquents\User.php

class User extends Eloquent implements AuthenticatableContract, AuthorizableContract
{
    // 認証機能を Eloquent モデルに紐づけ
    use Authenticatable;
    use Authorizable;

    /**
     * ユーザ認証機能に紐づいたパスワードハッシュ機能でハッシュ化された文字列を取得
     * @param $plain
     * @return string
     */
    public static function makePassword($plain): string
    {
        // このモデルの紐づいた認証機能のガードから順にパスワードハッシュ機能まで辿っていき、ハッシュをかけます。
        /** @var SessionGuard $guard */
        $guard = Auth::guard('web');
        /** @var EloquentUserProvider $authProvider */
        $authProvider = $guard->getProvider();

        // この hasher がデフォルトで \Hash::class のサービスコンテナと紐づいています
        return $authProvider->getHasher()->make($plain);
    }
}

 こんな感じで Laravel のパスワードアルゴリズムをカスタマイズできますが特別な事情がない限りカスタマイズはせず、安全なアルゴリズムであるデフォルトのアルゴリズムを使用するのが推奨されます。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG