Customize Laravel Auth — Laravel Breeze Authentication

MD. Arif Ahmed
3 min readJan 25, 2023
laravel Custom Auth

Hello Artisans, we love PHP and Laravel. You are reading this post that means you are developing something amazing in Laravel. Sometimes we need to customize the Laravel Default authentication system and for the first time we don’t know how to do it. Let’s start.

By default, Laravel uses email field for authentication but sometimes we need to change that. Like users can login using username or phone number or anything and how can we do that on Laravel. I am considering username.

Step 1: Edit the RegisteredUserController

Go to app/Http/Controllers/Auth/RegisteredUserController.php file and customize the store method to this

public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'username' => ['required', 'string', 'max:255', 'unique:'.User::class],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);

$user = User::create([
'name' => $request->name,
'username' => $request->username,
'password' => Hash::make($request->password),
]);

event(new Registered($user));

Auth::login($user);

return redirect(RouteServiceProvider::HOME);
}

In the validate method, I removed the email and added username. Also, create a user with username field.

Step 2: Modify the User Model

We need to remove the email field and add username field on the $fillable property. Go to app/Models/User.php

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

Step 3: Modify the Registration View

Go to resources/views/auth/register.blade.php and modify the form just like this

<form method="POST" action="{{ route('register') }}">
@csrf
<!-- Name -->
<div>
<x-label for="name" :value="__('Name')" />

<x-input id="name" class="block mt-1 w-full" type="text" name="name" required autofocus />
</div>
<!-- Name -->

<div>
<x-label for="username" :value="__('username')" />

<x-input id="username" class="block mt-1 w-full" type="text" name="username" required />
</div>

<!-- Password -->
<div class="mt-4">
<x-label for="password" :value="__('Password')" />

<x-input id="password" class="block mt-1 w-full" type="password" name="password" required autocomplete="new-password" />
</div>

<!-- Confirm Password -->
<div class="mt-4">
<x-label for="password_confirmation" :value="__('Confirm Password')" />

<x-input id="password_confirmation" class="block mt-1 w-full" type="password" name="password_confirmation" required />
</div>

<div class="flex items-center justify-end mt-4">
<x-button>
{{ __('Register') }}
</x-button>
</div>
</form>

Step 4: Modify the login View

Go to resources/views/auth/login.blade.php and modify the form just like this

<form method="POST" action="{{ route('login') }}">
@csrf

<!-- Username -->
<div>
<x-label for="username" :value="__('Username')" />

<x-input id="username" class="block mt-1 w-full" type="text" name="username" required autofocus />
</div>

<!-- Password -->
<div class="mt-4">
<x-label for="password" :value="__('Password')" />

<x-input id="password" class="block mt-1 w-full" type="password" name="password" required autocomplete="current-password" />
</div>

<!-- Remember Me -->
<div class="block mt-4">
<label for="remember_me" class="flex items-center">
<input id="remember_me" type="checkbox" class="form-checkbox" name="remember">
<span class="ml-2 text-sm text-gray-600">{{ __('Remember me') }}</span>
</label>
</div>

<div class="flex items-center justify-end mt-4">
@if (Route::has('password.request'))
<a class="underline text-sm text-gray-600 hover:text-gray-900" href="{{ route('password.request') }}">
{{ __('Forgot your password?') }}
</a>
@endif

<x-button class="ml-3">
{{ __('Login') }}
</x-button>
</div>
</form>

Step 5: Modify the Login Request Class

Go to app/Requests/Auth/LoginRequest.php and change all the email fields to username also change the validation rules

class LoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'username' => ['required', 'string'],
'password' => ['required', 'string'],
];
}

/**
* Attempt to authenticate the request's credentials.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function authenticate(): void
{
$this->ensureIsNotRateLimited();

if (! Auth::attempt($this->only('username', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());

throw ValidationException::withMessages([
'username' => trans('auth.failed'),
]);
}

RateLimiter::clear($this->throttleKey());
}

/**
* Ensure the login request is not rate limited.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function ensureIsNotRateLimited(): void
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}

event(new Lockout($this));

$seconds = RateLimiter::availableIn($this->throttleKey());

throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}

/**
* Get the rate limiting throttle key for the request.
*/
public function throttleKey(): string
{
return Str::transliterate(Str::lower($this->input('username')).'|'.$this->ip());
}
}

Now you are done. Now you can use the username field instead of email to login to Laravel.

--

--