Laravel Authenticate with Username or Email

Laravel Authenticate with Username or Email

Learn how to implement authentication that allows users to login using either their username or email address.

Introduction

By default, Laravel's authentication system uses email for login. This guide will show you how to modify the authentication system to accept either username or email for login.

Prerequisites

  • Laravel 6.x or higher
  • Basic authentication setup
  • Database with users table
  • Understanding of Laravel authentication

1 Update User Model

Add username field to your User model:

protected $fillable = [
    'name',
    'username',
    'email',
    'password',
];

Add username to the database:

php artisan make:migration add_username_to_users_table --table=users

Update the migration file:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('username')->unique()->after('name');
    });
}

2 Modify Login Controller

Create a custom login controller:

php artisan make:controller Auth/LoginController

Update the controller:

use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected function credentials(Request $request)
    {
        $field = filter_var($request->input('login'), FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
        $request->merge([$field => $request->input('login'), 'password' => $request->input('password')]);
        
        return $request->only($field, 'password');
    }

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

3 Update Login Form

Modify the login form in `resources/views/auth/login.blade.php`:

<div class="form-group row">
    <label for="login" class="col-md-4 col-form-label text-md-right">{{ __('Username or Email') }}</label>

    <div class="col-md-6">
        <input id="login" type="text" class="form-control @error('login') is-invalid @enderror" 
               name="login" value="{{ old('login') }}" required autofocus>

        @error('login')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>
</div>

4 Update Routes

Update your authentication routes in `routes/web.php`:

Auth::routes([
    'login' => 'Auth\LoginController@showLoginForm',
    'post' => 'Auth\LoginController@login',
]);

5 Update Registration

Modify the registration controller to include username:

protected function create(array $data)
{
    return User::create([
        'name' => $data['name'],
        'username' => $data['username'],
        'email' => $data['email'],
        'password' => Hash::make($data['password']),
    ]);
}

Update the registration form:

<div class="form-group row">
    <label for="username" class="col-md-4 col-form-label text-md-right">{{ __('Username') }}</label>

    <div class="col-md-6">
        <input id="username" type="text" class="form-control @error('username') is-invalid @enderror" 
               name="username" value="{{ old('username') }}" required>

        @error('username')
            <span class="invalid-feedback" role="alert">
                <strong>{{ $message }}</strong>
            </span>
        @enderror
    </div>
</div>

Key Features Covered

  • Username field addition
  • Custom login controller
  • Login form modification
  • Route updates
  • Registration updates
  • Validation handling

Best Practices

  • Validate username format
  • Add unique constraints
  • Implement proper error messages
  • Add username validation rules
  • Consider case sensitivity

Common Issues

  • Duplicate usernames
  • Case sensitivity issues
  • Validation errors
  • Route conflicts
  • Session handling