DEV Community

FerminAlvarez
FerminAlvarez

Posted on

Multiple Roles Authentication in Laravel with Breeze

Multiple Roles Authentication in Laravel

Authentication is a fundamental aspect in web applications, allowing users to access specific features and resources securely. In Laravel, a popular PHP web framework, the Breeze Multi-Auth package provides a powerful solution to handle authentication with multiple user roles efficiently. This tutorial aims to guide you through the process of setting up a Laravel project with Breeze Multi-Auth

Laravel Project Creation

To get started, we need to create a Laravel project by following these steps:

  • Install the Laravel package if you don't have it installed yet:
composer global require laravel/installer
Enter fullscreen mode Exit fullscreen mode
  • Create a new Laravel project named 'multiauth': (The library we are going to use, at the time of writing this post, has support up to Laravel 9):
composer create-project laravel/laravel=9.* multiauth
Enter fullscreen mode Exit fullscreen mode
  • Navigate to the project directory:
cd multiauth
Enter fullscreen mode Exit fullscreen mode
  • Start the development server:
php artisan serve
Enter fullscreen mode Exit fullscreen mode

Before proceeding, make sure to create a new database and associate it in the .env file. This database will be used for storing the application's data.

If the server is running correctly, we can proceed with the installation of Breeze.

Installing Breeze Multi-Auth Package

Next, we'll install the painlesscode/breeze-multiauth package, which will provide us with the necessary tools for multiple roles authentication.

composer require painlesscode/breeze-multiauth
Enter fullscreen mode Exit fullscreen mode

Creating Roles

Now, we'll create three roles: Administrator, Student, and Teacher using the breeze:multiauth command.

php artisan breeze:multiauth Administrator
php artisan breeze:multiauth Student
php artisan breeze:multiauth Teacher 
Enter fullscreen mode Exit fullscreen mode

Once we have defined the roles, we'll execute the migrations to create the required tables in the database and start the server:

php artisan migrate
php artisan serve
Enter fullscreen mode Exit fullscreen mode

Now we can access it at:
http://127.0.0.1:8000/student/
http://127.0.0.1:8000/student/register

http://127.0.0.1:8000/administrator/
http://127.0.0.1:8000/administrator/register

http://127.0.0.1:8000/teacher/
http://127.0.0.1:8000/teacher/register

Customizing the User Table

If we want to change the user table, we need to make some changes.
For example to add a nickname field to a student in Database>Migrations>create_students_table.php:

Schema::create('students', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('nickname'); // Added 'nickname' field
    $table->string('email')->unique();
    $table->timestamp('email_verified_at')->nullable();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});
Enter fullscreen mode Exit fullscreen mode

In App>Http>Controllers>Student>Auth>RegisteredUserController.php:

Auth::guard('student')->login($student = Student::create([
    'name' => $request->name,
    'nickname' => $request->nickname, // Added 'nickname' field
    'email' => $request->email,
    'password' => Hash::make($request->password),
]));
Enter fullscreen mode Exit fullscreen mode

In App>Models>Student.php:

protected $fillable = [
    'name',
    'nickname', // Added 'nickname' field
    'email',
    'password',
];
Enter fullscreen mode Exit fullscreen mode

In Resources>Views>Student>auth-register.blade.php
Add the following field to the form:

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

    <x-input id="nickname" class="block mt-1 w-full" type="text" name="nickname" :value="old('nickname')" required autofocus />
</div>
Enter fullscreen mode Exit fullscreen mode

After making these changes, run the following command to apply the new migration:

php artisan migrate:refresh
php artisan serve
Enter fullscreen mode Exit fullscreen mode

Once you register a new user at http://127.0.0.1:8000/student/register and check the database, you will find the 'nickname' associated with the user.

Username Authentication

If we prefer users to log in using their username instead of email, we can customize this behavior.
To enable users to log in using their nickname instead of their email, follow these steps:

  • Open the file App>Http>Requests>Student>Auth>LoginRequest.php and modify the validation rules as shown below:
public function rules()
{
    return [
        //'email' => 'required|string|email', old login method
        'nickname' => 'required|string',
        'password' => 'required|string',
    ];
}

Enter fullscreen mode Exit fullscreen mode
  • Update the authenticate() function in the same file to use the 'nickname' field during the login attempt:
public function authenticate()
{
    $this->ensureIsNotRateLimited();

    if (!Auth::guard('student')->attempt($this->only('nickname', 'password'), $this->filled('remember'))) {
        RateLimiter::hit($this->throttleKey());

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

    RateLimiter::clear($this->throttleKey());
}
Enter fullscreen mode Exit fullscreen mode
  • In the same file, ensureIsNotRateLimited() method, update the validation error message to use 'nickname' instead of 'email':
public function ensureIsNotRateLimited()
{
    // ...
    throw ValidationException::withMessages([
        'nickname' => trans('auth.throttle', [
            'seconds' => $seconds,
            'minutes' => ceil($seconds / 60),
        ]),
    ]);
}

Enter fullscreen mode Exit fullscreen mode
  • Update the throttleKey() method in the same file to use 'nickname' instead of 'email':
public function throttleKey()
{
    return Str::lower($this->input('nickname')).'|'.$this->ip().'|student';
}
Enter fullscreen mode Exit fullscreen mode
  • In the Resources>Views>Student>login.blade.php file, update the form label and input field to use 'Nickname' instead of 'Email Address':
<!-- Nickname -->
<div>
    <x-label for="nickname" :value="__('Nickname')" />

    <x-input id="nickname" class="block mt-1 w-full" type="text" name="nickname" :value="old('nickname')" required autofocus />
</div>
Enter fullscreen mode Exit fullscreen mode

That's it! Now, users can log in with their nickname instead of their email.

I hope this report helps you understand how to implement multiple roles authentication in Laravel using the Breeze Multi-Auth package.

Good luck with your development! If you have any questions or concerns, feel free to share them in the comments

Written by

Fermin Alvarez
Selene Gonzalo

Top comments (0)