Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Caspian's avatar

Login by username in Laravel 5.3?

There are a lot of tutorials out there on how one can implement login with username instead of email addresses for past version of Laravel. However I can't quite get it working in Laravel 5.3 since I'm new to it all. I'm using the regular authentication system that you can generate with artisan make:auth.

  1. I edited my view form.
  2. Made DB migration with username field and all that, no problems on DB side I believe.
  3. Added "protected $username = 'username'" to my LoginController and RegisterController.
  4. Added rule to validator.
  5. Added username to $fillable so it's mass-assignable.
  6. Added error message for 'username' into language file.

When I try to login with username, the page refreshes and login page shows again without any errors or anything new. It doesn't log me in and doesn't redirect either. I believe the problem is in my view because of no returned errors but I could be wrong. Here is my form-group:

                        <div class="form-group{{ $errors->has('username') ? ' has-error' : '' }}">
                            <label for="username" class="col-md-3 control-label">Username</label>

                            <div class="col-md-9">
                                <input id="username" type="text" class="form-control" name="username" value="{{ old('username') }}" autofocus>

                                @if ($errors->has('username'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('username') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

What could be the problem? Any help is appreciated.

0 likes
20 replies
jlrdw's avatar

You did create a username field in the users table? Where there is email to login replace with username, and validate as text not email, that's all. It is really that simple.

denpun's avatar

In 5.3 you need to override the following function

public function username()

Look in: vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php

The default is to return email:

public function username()
{
        return 'email';
}

After adding the fields in your db, you can override as follows in your controller

public function username()
{
        return 'username';
}
8 likes
jlrdw's avatar

Don't mess with vendor, just do like I said.

jlrdw's avatar
Specifying Additional Conditions

If you wish, you also may add extra conditions to the authentication query in addition to the user's e-mail and password. For example, we may verify that user is marked as "active":

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
    // The user is active, not suspended, and exists.
}

    In these examples, email is not a required option, it is merely used as an example. You should use whatever column name corresponds to a "username" in your database.

Change above to

if (Auth::attempt(['username' => $username, 'password' => $password, 'active' => 1])) {
    // The user is active, not suspended, and exists.
}

DO NOT MESS WITH VENDOR.

usman's avatar

@jlrdw denpun's solution is not suggesting the OP to mess with the vendor folder. The correct way is indeed to override the username method inside the AuthOrWhatever controller it is (LoginController).

4 likes
usman's avatar

he said Look in: vendor/laravel/framework/src/Illuminate/Foundation ...

@jlrdw I am not argueing :). Looking at something does not mess that thing up.

Have a nice day.

denpun's avatar

@usman : Indeed and thanks for the clarification.

@jlrdw: I was just pointing to the vendor file for reference to the function username().

I said override, implying in one's own controller class. Editing the vendor files would not necessarily be overriding, just editing I guess. :)

In 5.2 there is no such function but they check for the existence of a username property. You can create a property like some tutorials suggest.

In 5.3 there is new function: function username() which returns the name of the field to be used as a username. There is no 5.2 like check for the existence of a username property. One needs to override the function username() in one's OWN controller and preferably NOT change the vendor code. Hopefully that is clear enough :)

Cheers and have a good day.

3 likes
jekinney's avatar

The issue with editing anything in the vendor folder is anytime a composer update it's possible that it will replace the edited file.

zachleigh's avatar

@jekinney The suggestion doesnt touch vendor at all. It simply overrides a method in a vendor file in a child controller class in app.

1 like
Snapey's avatar

As for not displaying any errors, make sure you don't have web middleware mentioned in your routes file (routes.php or routes\web.php)

Run php artisan:list to check web is listed once only per route.

nate.a.johnson's avatar

It never hurts to dig deep into the vendor folder and see how things work... come on, use the source Luke. The beauty of open source is that if you need to, you can modify the vendor code. Just realize that upgrading might be more difficult. And for that matter, you don't have to upgrade. I have a project that's over 100,000 lines of code (not counting vendor) and it's still running on Laravel 4.2. It's working just fine and the only thing I upgrade are security issues.

The people that try to scare others away from vendor really need to take a step back from the ledge.

3 likes
simondavies's avatar

furher to add to @denpun mehtod is to basically:

Open up your LoginController.php and add the following method as @denpun mentions.

in App\Http\Controllers\Auth\LoginController.php

/**
    * Override the username method used to validate login
    *
    * @return string
    */
    public function username()
    {
        return 'username';
    }

This will simply overwrite the current one to the field you want to use, in this case username instead of email. You can do the odd other one like i have below for EG:

I'm using an admin folder in my views rather than auth so i am overriding the auth.login

public function showLoginForm()
    {
        return view('admin.login');
    }

I'm also changing my redirect from the home to a dashboard route:

protected $redirectTo = '/dashboard';

Hope this helps others.

5 likes
mozgus_'s avatar

Hello all, I've added column username in users table and edited my Login view:

Username
                        <div class="col-md-6">
                            <input id="username" type="text" class="form-control" name="username" value="{{ old('username') }}" required autofocus>

                            @if ($errors->has('username'))
                                <span class="help-block">
                                    <strong>{{ $errors->first('username') }}</strong>
                                </span>
                            @endif
                        </div>
                    </div>

Also, I've added this in my login controller:

protected $username = 'username';

and

public function username() { return 'username'; }

But, every time when I try to login it says that I use bad credentials, I'm sure that my credentials are correct.

Any suggest? Thanks

jekinney's avatar

Keep in mind the default make:auth scaffolding is set to use either or. So dive into that code and see how Taylor does it.

riddict's avatar

I got the same problem as @mozgus_ I add the username method on logincontroller, and change the input name to username. But everytime i try to login always return "These credentials do not match our records."

lipsum83's avatar

I got this credentials error also, in my case the problem was because I was seeding the information and the password I was seeding was not encrypted, laravel uses a facade that hashes the password field for authentication, I solved it using the Hash facade

Here is what I changed on the seeding file in order to encrypt the password

DB::table('tableName')->insert([ 'account' => 'COMPANYACCOUNT', 'password' => Hash::make('123456789'), 'created_at' => \Carbon\Carbon::now(), 'updated_at' => \Carbon\Carbon::now(), ]);

fchong's avatar

I'm looking for solution as well. I tried this straight forward way although it is not recommended to mess with the vendor folder.

In: vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php

public function username()
{
    // return 'email';
    return 'name';
}

Replace 'email' to ''name' instead of 'username' as the DB already include name field. We don't need to create other 'username' column. In: /resources/views/auth/login.blade.php

<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
    <label for="name" class="col-md-4 control-label">E-Mail Address replaced to Name</label>

    <div class="col-md-6">
        <input id="name" type="name" class="form-control" name="name" value="{{ old('name') }}" required autofocus>

        @if ($errors->has('name'))
            <span class="help-block">
                <strong>{{ $errors->first('name') }}</strong>
            </span>
        @endif
    </div>
</div>

Please or to participate in this conversation.