Search code examples
phplaravellaravel-8laravel-livewirelaravel-jetstream

authenticating in laravel 8 with jetstream - username or email


I am searching for a solution to change the standard Jetstream Auth to Auth with username or email. This means during the registration of the account you enter email or username (username is always required). In the login form you can enter username or email as your credentials. I have also changed in the profile settings to update also the username.

My actual problems are

  1. during registration only with the username I get the error of the empty email field registration error

  2. during login the username will be not a correct credential

I have changed everything similar to the post Problem authenticating with username and password in Laravel 8 but it doesn't work.

1. change in config/fortify.php

'username' => 'email' to 'username' => 'identity'

2.added authentication code to app/Providers/FortifyServiceProvider.php inside boot method

Fortify::authenticateUsing(function (LoginRequest $request) {
        $user = User::where('email', $request->identity)
            ->orWhere('username', $request->identity)->first();

        if (
            $user &&
            \Hash::check($request->password, $user->password)
        ) {
            return $user;
        }
    });

and also added classes

use Laravel\Fortify\Http\Requests\LoginRequest;
use App\Models\User;

3. added username during register Add input field unter register.blade.php

<div class="mt-4">
            <x-jet-label for="username" value="{{ __('User Name') }}" />
            <x-jet-input id="username" class="block mt-1 w-full" type="text" name="username" :value="old('username')" required autofocus autocomplete="username" />
</div> 

and deleted the required from the email form field.

4.add username to the User model

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

change in app/Actions/Fortify/CreateNewUser.php

Validator::make($input, [
        'name' => ['required', 'string', 'max:255'],
        'email' => ['string', 'email', 'max:255', 'unique:users'],
        'username' => ['required', 'string', 'max:255', 'unique:users'],
        'password' => $this->passwordRules(),
    ])->validate();

    return User::create([
        'name' => $input['name'],
        'email' => $input['email'],
        'username' => $input['username'],
        'password' => Hash::make($input['password']),
    ]);

5. added username field to database

Schema::table('users', function (Blueprint $table) {
        $table->string('username')->nullable();
    });

Solution

  • In your first case where username is required but email is optional, you will need to add nullable to your validation properties. Please check the docs on optional fields.

    For you second use case, login.blade.php the default input tag is name="email". That means your condition will be $user = User::where('email', $request->email)->orWhere('username', $request->email)->first();

    Check Customizing User Authentication on Laravel Fortify.