0

I am struggling with using Laravel's built-in auth against an existing 'Users' table that already contains username and password. The column names are 'UserEmail' and 'UserPassword'. To test it out, I used tinker to create an entry, hashing the password as:

$user->UserPassword=Hash::make('1234');

When trying to log in using Auth::attempt, authentication keeps failing. To debug, I started adding var_dump and even do a comparison of the password request that comes through against the hashed password in the database and it matches. So I am not sure why the Auth::attempt fails to authenticate it:

This is the function I have in my LoginController.php:

public function login(Request $request)
{
    // validate the form data
    $this->validate($request, [
        'UserEmail' => 'required',
        'UserPassword' => 'required'
    ]);

    var_dump($request->UserEmail);
    var_dump($request->UserPassword);
    $user = App\FarmUser::where('UserEmail', $request->UserEmail)->first();
    var_dump($user->UserPassword);
    $authenticated = Hash::check($request->UserPassword, $user->UserPassword);
    var_dump($authenticated);

    // attempt to log the user in
    if (Auth::attempt(['UserEmail' => $request->UserEmail, 'UserPassword' => $request->UserPassword], $request->remember)) {
        // if successful, then redirect to their intended location
        Debugbar::addMessage('successfully authenticated');
        return redirect()->intended($redirectTo);   
    }

    // if unsuccessful, then redirect back to login with the form data
    Debugbar::addMessage('authentication failed');
    //return redirect()->back();
}

When I try to log in, I see the correct UserEmail, UserPassword, and the hash check also returns true. However, when I call the Auth::attempt, it does not successfully authenticate and redirects back. Any idea why I can't get the Auth::attempt to authenticate properly?

When I log in, this is the output generated from those var dumps:

string(20) "user@test.com" string(8) "1234" string(60) "<hash>" bool(true)

Here is what tinker returns for this App\FarmUser model:

>>> $user = App\FarmUser::where('UserLogin', 'testuser')->first();
=> App\FarmUser {#809
     ID: 1,
     UserLogin: "testuser",
     password: "<hash>",
     Active: "Yes",
     UserEmail: "user@test.com",
     Created: "2018-03-20 15:09:24",
     CreatedByID: null,
     Modified: null,
     ModifiedByID: null,
     created_at: "2018-03-20 19:09:09",
     updated_at: "2018-03-20 19:09:09",
   }
derekmw
  • 375
  • 1
  • 5
  • 13
  • if the table is empty i would recommend naming them in the standard way and avoiding camel case in naming column https://stackoverflow.com/questions/25475287/what-rules-apply-to-naming-a-mysql-column. Also check this for your issue https://stackoverflow.com/questions/41342907/laravel-authattempt-returns-false – Indra Mar 22 '18 at 16:05
  • Thanks, as I read up on Laravel, that has become apparent about the naming. Unfortunately, the reason I have these naming conventions is I am trying to build this off an existing MySQL database that has this naming convention. – derekmw Mar 22 '18 at 16:21

1 Answers1

2

You will need to override the getAuthPassword() method in your User model, like this:

/**
 * Get the password for the user.
 *
 * @return string
 */
public function getAuthPassword()
{
    return $this->UserPassword;
}

And don't call UserPassword in your Auth::attempt(), but call it password. Like this:

Auth::attempt([
    'UserEmail' => $request->UserEmail, 
    'password' => $request->UserPassword
]);

This is because Laravel can't recognize which fields are supposedly a password field and has a "reserved" word "password" for it (it will perform a hash on that field, but not others).

Edit:

Since your model is actually \App\FarmUser, you also need to change it in the config/auth.php file, like so:

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\FarmUser::class,
    ],

    // 'users' => [
    //     'driver' => 'database',
    //     'table' => 'users',
    // ],
],
DevK
  • 9,597
  • 2
  • 26
  • 48
  • Ok, so I tried this (I assume I need to add that getAuthPassword function to my other model I'm trying to use - FarmUser correct? I added that and changed my attempt call, but still not validating. Thanks for the tip on the 'password' naming in the attempt call. That makes sense...however, like I said, it's still not authenticating for some reason. – derekmw Mar 22 '18 at 16:19
  • What is very odd, if I use tinker and grab the 1 row I have in the table, the colunmn which is called 'UserPassword' shows up as 'password'. (see my update in original post). Could this be causing the issue? – derekmw Mar 22 '18 at 16:49
  • Oh, I didn't realize earlier that your model is `FarmUser`. You need to update `config/auth` as well then. See my edit. – DevK Mar 22 '18 at 17:01
  • I should have mentioned that, yes I already have the config/auth modified as you stated. I actually created a new provider called 'farmusers' but just to be sure there are no other odd hard coding in auth mechanism, I changed the guard back to call 'users' and modified the 'users' provider as you mentioned above, but still no change. arg... – derekmw Mar 22 '18 at 17:15
  • Hmm, then I'm slowly running out of ideas. Can you do this: put `\DB::enableQueryLog();` before `Auth::attempt(...)` call and `\Log::info(\DB::getQueryLog())` after the auth attempt? Then check storage/laravel.log what query is ran for `Auth::attempt(..)` – DevK Mar 22 '18 at 17:21
  • Also, just want to check - does your `FarmUser` extend `Authenticatable`? – DevK Mar 22 '18 at 17:27
  • The log shows what I would expect. Query is 'select * from `FarmUsers` where `UserEmail` = ? limit 1' and the array shows 1 element - 'user@test.com' – derekmw Mar 22 '18 at 17:27
  • Yes, I have it defined as: class FarmUser extends Authenticatable – derekmw Mar 22 '18 at 17:27
  • Hmm everything seems correct then. It's just not comparing the password from request to the correct column. Which overriding the `getAuthPassword()` should solve. No idea why it doesn't work for you really. – DevK Mar 22 '18 at 17:41
  • Are you completely sure that your password column is called `UserPassword`? From the tinker dump in your question it seems it might be just `password`. In that case you shouldn't override the `getAuthPassword()`, just do `Auth::attempt(['UserEmail' => $req->UserEmail, 'password' => $req->UserPassword])` – DevK Mar 22 '18 at 17:45
  • You are completely right on the column name. I forgot I changed it because of this issue and I was trying to see how I could get it to work. I renamed the column back to UserPassword but it still doesn't work. I started a new project from scratch and this time it works though. So I'm not exactly sure what I was doing wrong but something somewhere was still causing Auth to look somewhere else it seems. – derekmw Mar 22 '18 at 19:53