Do you really need entrust or laravel-permission to implement your authorization?

Original author: Adel F
  • Transfer
“So ... I need a simple authorization. Any admin role, and can be an editor / moderator. Now google. ABOUT! For laravel there are already ready packages! zizaco / entrust , spatie / laravel-permission and others! Let's pick some! ”

Something like this happens. Then the migration of the package adds 5 plates to the database to store the roles, permissions and their relationships. All authorization rules, such as the 'admin' and 'editor' roles can do 'edit posts' , are stored in these tables. Typically, a project has many copies of the database. Copies of developers, test base (s) and production. As a result, all these authorization rules are forced to synchronize between databases.

I met a couple of projects where there was one main copy of the rules in the production database and the rest copied everything from there.

The idea of ​​using the Seeder class ( example ) is much better. You just need to run

php artisan db:seed AuthSeeder

and you have a fresh version of the rules in the database. Thus, this seeder class becomes some kind of Single Source Of Truth. Good, but there is still a lot of inconvenience in this approach:

  • Seeder must be pretty smart not only to create roles and permissions and connections between them, but also to synchronize old versions. Those. remove or create links between roles and permishenes if necessary.
  • The rules are stored in the database and constant synchronization between them is necessary. Each change to the requirements of the form “editors should not now edit posts, only publish them” leads to a change in seeder, synchronization of the code base via git or something, and “DO NOT FORGET TO RUN AuthSeeder!”
  • Authorization rules can be complicated. For example, a publication can be edited not only by editors or administrators, but also by the author of this publication. Therefore, instead of simple middleware:

['middleware' => ['permission:edit posts']]

developers should use standard laravel authentication:

classPostPolicy{
    publicfunctionedit(User $user, Post $post){
         return $user->id == $post->owner_id 
             || $user->hasPermissionTo('edit posts');
    }
}

So maybe the easiest way is not the best?


It only looks simple: put the package, run the finished migration and go. In terms of long-term project support, this is not the best choice.

Let's try to analyze what projects usually need? Simple role system. Almost always one role per user. Administrator. Well, maybe another editor or moderator. And these roles have certain permishes. Let's go the most direct way! Add a new field to the users table! is_admin or role . Then a couple of helper methods to the User class :

classUser{
    publicfunctionisAdmin(): bool{...}
    publicfunctionisEditor(): bool{...}
}

Now permisheny. Laravel provides two basic methods for their description: Gates and Policies . I will use gates (there is still a small trick with the function in a variable, but for fans of functional programming this is not a trick at all):

    $isAdmin = function(User $user){
        return $user->isAdmin();
    }
    $isEditorOrAdmin = function(User $user){
        return $user->isAdmin() || $user->isEditor();
    }
    Gate::define('foo-permission', $isAdmin);
    Gate::define('bar-permission', $isAdmin);
    Gate::define('editor-permission', $isEditorOrAdmin);
    // Complex permission
    Gate::define('edit-post', function(User $user, Post $post){
         return $user->id == $post->owner_id 
            || $user->isAdmin();
    });

If the project needs several roles per user, then we simply add the user_roles table and change the User helper methods . The contents of the seeder class for * trust packages and this code-based authorization are almost identical! But the rules are now simply stored in the code and there is no need to constantly synchronize them in the databases.

I do not want to say that these packages are useless. This approach is very useful in projects with a complex authorization system, where the client himself wants to set up roles later. And then there are projects with dynamic permishenami. Example: forum with subforums. Each subforum can have its own moderators, each moderator has certain administrator rights in this subforum. Another example is the telegram and its group. There is the same thing. Such projects really need a complex, stored in a database authorization system with all its problems. But most others are not.

The package situation for laravel becomes similar to the situation with components for Delphi (old people remember). Packages put without hesitation - really needed or not.

So, here in my project I would have to count $ a + $ b. Is there any laravel-sum package?

PS I apologize for the "permishena", but I did not find a good accurate translation.

Also popular now: