Laravel 5 Berechtigungen

Eine Anleitung wie man ein Berechtigungssystem in Laravel erstellt.

Ich erkläre hier anhand eines Beispiels wie man ein flexibles Berechtigungssystem in Laravel erstellt. Dafür benutze ich Gates und Policies die schon in Laravel integriert sind sodass man keine zusätzlichen Pakete installieren muss. Grundkenntnisse in Laravel sind natürlich Voraussetzung. 

Hier die offizielle Anleitung: https://laravel.com/docs/5.8/authorization

 

Was sind Gates und  Policies?

Einfach erklärt kann man mit Gates und Policies Bedingungen setzen sodass ein Benutzer eine bestimmte Berechtigung braucht um Daten/Seiten zu sehen, bearbeiten, erstellen oder löschen.

Folgende Links haben mir geholfen Gates und Policies besser zu verstehen:

https://kodigo.me/how-to-implement-laravel-authorization-using-gates/

https://quickadminpanel.com/blog/course-lesson-7-roles-permissions-and-authorization/

 

Zum Beispiel

Ich habe versucht das Beispiel so einfach wie möglich zu gestalten, für das habe ich neben der User Tabelle (Benutzer) nur noch die Role Tabelle (Rollen) erstellt.

Bei den Code-Beispielen ist nur der wichtige Teil der Datei zu sehen und nicht die komplette Datei.

Tabellen

create_users_table.php

public function up()

    {

        Schema::create('users', function (Blueprint $table) {

            $table->bigIncrements('id');

            $table->unsignedBigInteger('role_id');

            $table->string('name');

            $table->string('email')->unique();

            $table->timestamp('email_verified_at')->nullable();

            $table->string('password');

            $table->rememberToken();

            $table->timestamps();

                            

             $table->foreign('role_id')

                        ->references('id')

                         ->on('roles')

                         ->onDelete('cascade');

        });

    }

 

create_roles_table.php

public function up()

    {

        Schema::create('roles', function (Blueprint $table) {

            $table->bigIncrements('id');

             $table->string('name');

            $table->timestamps();

        });

    }

Beziehungen der Daten zueinander

User.php

public function role()

                {

                               return $this->belongsTo('App\Role');

                }

Role.php

public function users()

                {

                               return $this->hasMany('App\User');

                }

 

Damit es funktioniert muss die Migration der Roles Tabelle vor der Users Tabelle erfolgen (Datum anpassen), sonst wird das Feld role_id in der Tabelle Users nicht gefunden und es kommt zur Fehlermeldung. Zusätzlich vergebe ich  jeden Benutzer bei der Registrierung noch eine Rolle und so hat man eigentlich alles was man braucht um ein gutes Berechtigungssystem in Laravel zu erstellen.

Dazu gehe ich in die Datei \app\Http\Controllers\Auth\RegisterController.php und vergebe bei der Registrierung jeden Benutzer eine bestimmte Rolle, dazu muss natürlich diese Rolle (Id) schon erstellt worden sein, sonst kommts zur Fehlermeldung.

 

protected function create(array $data)

    {

        return User::create([

            'role_id' => '1',

            'name' => $data['name'],

            'email' => $data['email'],

            'password' => Hash::make($data['password']),

        ]);

    }

Gates

Man geht hierfür in die Datei \app\Providers\AuthServiceProvider.php erstellt die gewünschten Gates und bestimmt welche Rolle ein Benutzer haben muss.

Ich habe hier als Beispiel 2 Rollen genommen, admin und editor, diese Rollennamen müssen natürlich in der Tabelle Roles vorkommen, sonst geht es nicht. Um es einfacher zu halten habe ich die Gates genau gleich benannt.

public function boot()

    {

        $this->registerPolicies();

                              

        Gate::define('admin', function($user) {

           return $user->role->name == 'admin';

        });

                              

        Gate::define('editor', function($user) {

           return $user->role->name == 'editor';

        });

    }

Das wars eigentlich schon man kann jetzt die verschiedenen Berechtigungen setzen, man findet im Netz genügend Anleitungen wie man das macht.

Middleware

Route::resource('users', 'UserController')->middleware('can:admin');

Erklärung: Nur  Benutzer mit der Rolle admin können zugreifen, bei allen anderen kommt eine Fehlermeldung.

Controller

use Gate; (Oben in Controller einfügen nicht vergessen)

public function index()

    {

        if (Gate::allows('admin')) {

                                              

                                               $users = User::all();

                                               return view('users.index', compact('users'));

                                              

                               } else {

                                              

                                               echo 'Only Admin are allowed';

                               }

                              

    }

Erklärung: Nur  Benutzer mit der Rolle admin können zugreifen, bei alle anderen kann man zu einer Fehlerseite verweisen.

View

@can('admin')

Nur Benutzer mit der Rolle admin können das sehen

@elsecan('editor')

Nur Benutzer mit der Rolle editor können das sehen

@else

Alle anderen Benutzer können das sehen

@endcan

Policies

Sie werden empfohlen wenn man den einzelnen Aktionen in einem Controller eine bestimmte Berechtigung vergeben will. Man hat hierfür die Gates die man erstellt hat admin und editor und kann damit die verschiedenen Bedingungen setzen.

Als Beispiel um zu zeigen wie Policies funktionieren, erstelle ich eine RolePolicy Datei und stelle als Bedingung dass nur ein Benutzer mit der Rolle admin eine Rolle löschen darf.

Dafür erstelle die RolePolicy Datei : php artisan make:policy RolePolicy --model=Role

In der Datei \app\Providers\AuthServiceProvider,muss man noch die eben erstellte RolePolicy hinzufügen.

protected $policies = [

                                         'App\Role' => 'App\Policies\RolePolicy',

    ];

In die RolePolicy Datei schreibe ich folgendes rein: \app\Policies\RolePolicy

public function delete(User $user)

    {

        return $user->role->name == 'admin';

    }

In die RoleController Datei schreibe ich folgendes rein: \app\Http\Controllers\RoleController.php

public function destroy($id)

    {

                               $this->authorize('delete', Role::class);

                               $role = Role::findOrFail($id);

                               $role->delete();

                               return redirect('roles')->with('flash_message', 'Role has been deleted!');

    }

 

Kommentar eingeben