web-dev-qa-db-ja.com

変更方法/ Laravel 4およびLaravel 5ユーザー認証のカスタムパスワードフィールド名

Laravel認証を使用するときにデータベースのパスワードフィールドを変更したい。usersテーブルの列の名前をpasswdではなくpasswordにしたい。次のようなものを実行しようとした。

Auth::attempt(array(
    'user_name' => 'admin',
    'passwd' => 'hardpass',
));

しかし、それは機能しません。

また、Userモデルに次の関数を追加しようとしました。

public function getAuthPassword() {
    return $this->passwd;
}

しかし、それも何も変わりません。ユーザーはまだ認証されていません。 Laravelでデータベースのパスワードフィールド名を変更することは可能ですか?

11

情報

データベース内の他のすべてのフィールドを簡単に変更して、認証に使用できます。唯一の問題はpasswordフィールドにあります。

実際、passwordフィールドは何らかの方法でLaravel(多くの人が考える方法ではありません)にハードコードされているため、質問で渡したとおりに配列を渡すことはできません。

デフォルトでは、配列をattempt(およびおそらくvalidateonceなどの他のAuth関数)に渡す場合、次のようにします。

_Auth::attempt(array(
    'user_name' => 'admin',
    'password' => 'hardpass',
));
_

デフォルトのEloquentドライバーは、次のクエリを実行します。

_select * from `users` where `user_name` = 'admin' limit 1;
_

データベースからこのデータを取得した後、指定したパスワードを、作成されたUserオブジェクトのpasswordプロパティと比較します。

しかし、単に使用する場合:

_Auth::attempt(array(
    'user_name' => 'admin',
    'passwd' => 'hardpass',
));
_

次のクエリが実行されます。

_select * from `users` where `user_name` = 'admin' and `passwd` = 'hardpass' limit 1;
_

データベースにはユーザーが見つかりません(passwdにハッシュされたパスワードを保存します)。これは、Eloquentがクエリpasswordから削除しますが、他のデータを使用してクエリを実行するためです。また、ここで'passwd' => Hash:make($data['password'])を使おうとすると、ユーザーは見つかりますが、パスワードの比較は機能しません。

解決

解決策は非常に簡単です。次のように_Auth::attempt_を実行する必要があります。

_Auth::attempt(array(
    'user_name' => 'admin',
    'password' => 'hardpass',
));
_

ご覧のとおり、キーとしてpasswordを渡します(ただし、この列はusersテーブルに存在しません)。これは、この方法でのみEloquentドライバーがクエリの構築に使用しないためです。

ここで、Userモデル(_app/models/User.php_)ファイルに、次の関数を追加する必要があります。

_public function getAuthPassword() {
    return $this->passwd;
}
_

ご覧のとおり、ここではデータベースに実際に存在する列passwdを使用しています。

このように使用すると、任意の名前のパスワードが付いた列を作成でき、デフォルトのEloquentドライバーを引き続き使用できます。

テストするサンプルデータ

非常に簡単なテストを作成しました。

_app/routes.php_ファイルを次のように置き換える必要があります。

_Route::get('/', function () {

    if (Auth::check()) {
        echo "I'm logged in as " . Auth::user()->user_name . "<br />";
        echo "<a href='/logout'>Log out</a>";
    } else {
        echo "I'm NOT logged in<br />";


        Auth::attempt(array(
            'user_name' => 'admin',
            'password'  => 'hardpass',
        ));


        if (Auth::check()) {
            echo "Now I'm logged in as " . Auth::user()->user_name . "<br />";
            echo "<a href='/logout'>Log out</a>";
        } else {
            echo "I'm still NOT logged in<br />";
        }
    }


});

Route::get('/logout', function () {
    Auth::logout();
    return "You have been logged out";
});


Route::get('/db', function () {

    if (!Schema::hasTable('users')) {


        Schema::create('users', function ($table) {
            $table->engine = 'InnoDB';
            $table->increments('id');
            $table->string('user_name', 60)->unique();
            $table->string('passwd', 256);
            $table->rememberToken();
            $table->timestamps();
        });

        DB::table('users')->insert(
            [
                [
                    'user_name' => 'admin',
                    'passwd'    => Hash::make('hardpass'),
                ]
            ]
        );
    }

    echo "Table users has been created";
});
_
  1. 空のデータベースを作成し、接続データを_app/config/database.php_に設定します
  2. これで、_/db_ url、たとえば_http://localhost/yourprojectname/db_を実行して、ユーザーテーブルを作成できます。
  3. これで、_/_ url、たとえば_http://localhost/yourprojectname/_を実行できます。データベースのusersテーブルにpassword列がない場合でも、ユーザーがログインしていることがわかります。 (認証用のデータはフォームなしで文字列として渡されていますが、もちろん実際のアプリケーションではそれらを追加します)。このURLをもう一度実行できます。ユーザーはまだログに記録されているため、期待どおりに機能しています。
  4. _Log out_リンクをクリックすると、ログアウトされます

上記のLaravel5の変更

このソリューションは、Larave 4.2.9(上記のすべて)とLaravel 5)でテストされました。Laravel5ではすべてが同じように機能しますが、もちろん異なるパスでファイルを編集する必要があります。

  1. Userモデルは_app/User.php_ファイルにあります
  2. ルートは_app/Http/routes.php_ファイルにあります
  3. データベース構成ファイルは_config/database.php_ファイルにあります
52