11

I would like to change password field in database when using Laravel authentication. I want my column in users table has name passwd and not password. I tried to run something like this:

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

but it doesn't work.

I also tried to add in User model the following function:

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

but it also changes nothing. User is still not being authenticated. Is it possible in Laravel to change password field name in database ?

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
  • @JarekTkaczyk It's true, but there is no info there for user who want to have custom password column in database. OP mentioned just using `getAuthPassword` but for user who is looking for solution he still won't know what to do. I thought this Q&A will be helpful for other users to solve this problem step by step – Marcin Nabiałek Sep 27 '14 at 12:48
  • 1
    Just a hint - most of the time the most valuable answers are those short and consise, that precisely address the issue. – Jarek Tkaczyk Sep 27 '14 at 13:34
  • @MarcinNabiałek you saved my life this stupid custom field in my project has been driving me bananas – caro Jan 05 '17 at 12:29

1 Answers1

57

Information

You can change easy all other fields in database and use them for authentication. The only problem is with password field.

In fact password field is in some way hard coded in Laravel (but not the way many think) so you cannot just pass array as you passed in your question.

By default if you pass array to attempt (and probably other Auth functions like validate or once) if you do it this way:

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

default Eloquent driver will run the following query:

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

After getting this data from database it will compare password you gave with password property for User object that was created.

But if you simply use:

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

the following query will be run:

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

and no user will be found in database (in passwd you store hashed password). This is because Eloquent removes from query password but use any other data to run query. Also if you try here to use 'passwd' => Hash:make($data['password']) although user will be found, comparing password won't work.

Solution

Solution is quite easy. You need to run Auth::attempt like this:

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

As you see you still pass password as key (although this column doesn't exits in users table) because only this way Eloquent driver won't use it for building query.

Now in User model (app/models/User.php) file you need to add the following function:

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

As you see you use here the column that really exists in database: passwd.

Using it this way you can have column with password named anything you want and you can still use default Eloquent driver for it.

Sample data to test

I've created very simple test for it.

You just need to replace your app/routes.php file with the following:

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. Create empty database and set connection data in app/config/database.php
  2. Now you can run /db url for example http://localhost/yourprojectname/db just to create users table.
  3. Now you can run / url for example http://localhost/yourprojectname/ - as you see user is logged in even if in users table in database you don't have any password column (data for authentication has been passed as strings without any forms but of course in real application you will add them) . You can run this url once more time - as you see user is still logged so it is working as expected.
  4. If you click on Log out link, you will be logged out

Laravel 5 changes for above

This solution was tested in Larave 4.2.9 (everything as above) and also in Laravel 5. In Laravel5 everything works the same but you need of course edit files in different paths:

  1. User model is in app/User.php file
  2. routes are in app/Http/routes.php file
  3. Database config file is in config/database.php file
Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
  • thank you very much. I've been struggling with this for a few days. I was intuitively trying Auth::attempt(array( 'user_name' => 'admin', 'password' => 'hardpass', )); – devplayer May 10 '18 at 19:30
  • thank you very much. I've been struggling with this for a few days. I was intuitively trying Auth::attempt(array( 'user_name' => 'admin', 'member_password' => 'hardpass', )); the custom password field must be returned in the User model (e.g. app/User.php): public function getAuthPassword() { return $this->member_password; } – devplayer May 10 '18 at 19:36