Как изменить имя поля пользовательского пароля для аутентификации пользователя Laravel 4 и Laravel 5

Я хотел бы изменить поле пароля в базе данных при использовании аутентификации Laravel. Я хочу, чтобы мой столбец в таблице users имел имя passwd, а не password. Я попытался запустить что-то вроде этого:

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

но это не сработает.

Я также попытался добавить в модель User следующую функцию:

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

но он ничего не меняет. Пользователь по-прежнему не аутентифицирован. Возможно ли в Laravel изменить имя поля пароля в базе данных?

Ответ 1

Информация

Вы можете легко изменить все остальные поля в базе данных и использовать их для аутентификации. Единственная проблема заключается в поле password.

На самом деле поле password каким-то образом жестко закодировано в Laravel (но не так, как многие думают), поэтому вы не можете просто передать массив, когда вы передали свой вопрос.

По умолчанию, если вы передаете массив в attempt (и, возможно, другие функции Auth, такие как validate или once), выполните следующие действия:

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

По умолчанию драйвер Eloquent выполнит следующий запрос:

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

После получения этих данных из базы данных он будет сравнивать пароль, который вы указали с помощью свойства пароля для объекта User, который был создан.

Но если вы просто используете:

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 model (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";
});
  • Создайте пустую базу данных и установите данные соединения в app/config/database.php
  • Теперь вы можете запустить /db url например http://localhost/yourprojectname/db только для создания таблицы пользователей.
  • Теперь вы можете запустить / url, например http://localhost/yourprojectname/ - как вы видите, пользователь зарегистрирован, даже если в таблице users в базе данных нет столбца password (данные для аутентификации были пройдены как строки без каких-либо форм, но, конечно, в реальном приложении вы их добавите). Вы можете запустить этот URL еще раз - поскольку вы видите, что пользователь все еще зарегистрирован, поэтому он работает как ожидалось.
  • Если вы нажмете на ссылку Log out, вы выйдете из системы

Laravel 5 изменяется выше

Это решение было протестировано в Larave 4.2.9 (все как указано выше), а также в Laravel 5. В Laravel5 все работает одинаково, но вам нужно, конечно, редактировать файлы по разным путям:

  • User модель находится в файле app/User.php
  • маршруты находятся в app/Http/routes.php файле
  • Файл конфигурации базы данных находится в файле config/database.php