Associate users with roles and permissions

Last update: May 23, 2022

Social Card of Laravel Permission

Associate users with permissions and roles

Sponsor

If you want to quickly add authentication and authorization to Laravel projects, feel free to check Auth0's Laravel SDK and free plan at https://auth0.com/developers.

Latest Version on Packagist Total Downloads

Documentation, Installation, and Usage Instructions

See the DOCUMENTATION for detailed installation and usage instructions.

What It Does

This package allows you to manage user permissions and roles in a database.

Once installed you can do stuff like this:

// Adding permissions to a user
$user->givePermissionTo('edit articles');

// Adding permissions via a role
$user->assignRole('writer');

$role->givePermissionTo('edit articles');

Because all permissions will be registered on Laravel's gate, you can check if a user has a permission with Laravel's default can function:

$user->can('edit articles');

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Testing

composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security-related issues, please email [email protected] instead of using the issue tracker.

Postcardware

You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.

We publish all received postcards on our company website.

Credits

This package is heavily based on Jeffrey Way's awesome Laracasts lessons on permissions and roles. His original code can be found in this repo on GitHub.

Special thanks to Alex Vanderbist who greatly helped with v2, and to Chris Brown for his longtime support helping us maintain the package.

And a special thanks to Caneco for the logo

Alternatives

License

The MIT License (MIT). Please see License File for more information.

GitHub

https://github.com/spatie/laravel-permission
Comments
  • 1. Add model/permissions caching

    This adds substantial speed increases by caching the associations between models and permissions. Part of the changes focus on the PermissionRegistar, specifically caching for getPermissions(), thanks to @klincheg for these changes.

    The rest is focussed on caching calls to HasPermissionTo() in HasPermissions.php.

    The association is cached under a compound key comprised of the package key, the model and the permission: spatie.permission.cache.App.Models.User.12.Spatie.Permission.Models.Permissions.view-dashboard

    These values are also used as tags: spatie.permission.cache, App.Models.User.12, Spatie.Permission.Models.Permissions.view-dashboard (if tags are not supported then the package continues as before, as they are essential to this functionality)

    As we are still using the package cache key, then the already existing cache-busting should not need to be updated to account for these changes. However, the usage of the model and the permissions in the tags allow for future addition of model specific, or permission specific cache-busting, helping prevent the stampeding herd effect that larger applications may experience each time a permission or role is updated.

    Performance tests involved seeding a database with 250 users, who were assigned between 2 - 4 roles, which were assigned between 30 - 500 permissions. Then each permission for each user was tested:

    $this->users->each(function (User $user) {
        $user->getAllPermissions()->each(function (Permission $permission) use ($user) {
            $this->assertTrue($user->can($permission->name));
        });
    });
    

    I went through different variations of the above, some including non-assigned permissions, etc.

    These changes increase the speed of the checks from several minutes down to 4 - 20 seconds (approx 32000 assertions in a couple of seconds in some tests). And the database calls went from 1800+ to 0.

    Things to note/get feedback on are:

    • Is the current cache busting effective enough for these changes? I reviewed the tests and ran through some real-world examples and had no issues, but a second opinion would be great.
    • The changes to the config could be breaking
    • The naming of checkHasPermissionTo() inside HasPermissions could be confused with the newly added method checkPermissionTo()
    • Clutter. I'm concious this has added a fair bit of new methods and checks, and I don't want to clutter up the package.

    Closes #732 Fixes #759 Fixes #789

    Reviewed by fullstackfool at 2018-11-08 11:41
  • 2. Next major release -- Features/Requests for v3

    It feels like the last couple of months a lot of issues were related to the multi-guard functionality introduced in v2. Apart from that there have been some vague caching issues as well. Time to do something about that in v3 of the package.

    The multi-guard issue

    Supporting multiple guards has added a lot of complexity to the package and made it feel quite "heavy". The multi-guard functionality is definitely a selling point for this package but it also seems to confuse some users that are new to the framework and haven't learned about guards yet. Not to mention the countless times a misconfiguration in auth.php causes the wrong guard to be used.

    Some possible solutions:

    • completely dropping support for guards - as @drbyte and I discussed at Laracon removing all support for multiple guards would make the package a lot easier to maintain, simpler and lighter.
    • my personal favourite: drop guard support but keep Permissions and Roles polymorphic relations. This means any model can have roles and permissions but there's no extra functionality related to guards.
    • maintaining two branches: one with- and one without support for guards.

    Caching issue

    There's no interface or CLI tool that comes with the package to create and manage roles/permissions. This means a lot of users revert to editing the DB to manage permissions causing the cache to be rendered invalid. Even though it's well documented this seems to be an issue that keeps coming back. Maybe caching should be limited to a single request lifecycle by default and configurable for anyone that needs more anything else?


    Any thoughts on these two issues or suggestions for other features for v3 of the package are very welcome!

    Reviewed by AlexVanderbist at 2017-09-28 15:25
  • 3. $guarded value on Role/Permission class causes failure in latest laravel 7.x and 6.x

    With regards the latest laravel update that is documented here: Security Release: Laravel 6.18.35, 7.24.0

    And also the code change happened here in the 6.x branch https://github.com/laravel/framework/pull/33777

    These two updates have broken the functionality when you try to perform a with() query on the Roles model.

    For example I have the code:

    Role::orderBy('type')
        ->withCount('users')
        ->paginate();
    

    This gives the error:

    PHP Notice:  Undefined index: guard_name in app/vendor/spatie/laravel-permission/src/Models/Role.php on line 62
    TypeError: Argument 1 passed to getModelForGuard() must be of the type string, null given, called in app/vendor/spatie/laravel-permission/src/Models/Role.php on line 62
    

    It seems the solution is to just set the $guarded property to [] in the model classes.

    If someone is extending the class this is easy to fix, but unfortunately it isn't very clear immediately what error caused this.

    If it is alright with the maintainers I don't mind making the change to the model files to the code that will make it functional.

    System Info:

    Laravel: 6.18.35 PHP: 7.3.8 Permissions: 3.13

    Reviewed by ReeceM at 2020-08-10 09:51
  • 4. [Bug? 4.3.0] Checking Permission via can() return PermissionDoesNotExists

    Hi. First, thanks for this great packages. I've been using this packages since version 1.

    I have user with Role 'System Administrator', and this roles has permission named 'dashboard', 'logs', etc. When I'm checking the user's permission via can, it throws Spatie\Permission\Exceptions\PermissionDoesNotExist.

    • spatie/laravel-permission package version: 4.3.0
    • illuminate/framework package: v8.55.0

    PHP version: 8.0.7 Database version: MySQL 8.0.25

    This is not happening prior to version 4.3.0. We have traced this issue, and found that getPermissions on Spatie\Permission\PermissionRegistrar is the culprit here.

    This is how we resolve this problem:

            $permissions = $this->permissions->$method(static function ($permission) use ($params) {
                foreach ($params as $attr => $value) {
                    if ($permission->getAttribute($attr) == $value) {
                        return true;
                    }
                }
    
                return false;
            });
    

    I think the return value are swapped? If I swap the 'true' and 'false' value like above, it behaves normally, and I only get PermissionDoesNotExists exception only when I'm supplying it with wrong / invalid permission.

    Thanks

    Reviewed by shadowbane at 2021-08-18 04:30
  • 5. PermissionDoesNotExist while Permission actually does exist.

    Hello,

    I am trying to implement permissions in my pages to hide menu items, by example. Currently, I am using this:

    @if(auth()->user()->hasPermissionTo('view_admin_top_menu'))
    //content
    @endif
    

    But it keeps returning the PermissionDoesNotExist exception while I am very sure the permission is in the database. Also, @hasrole() works... so it is very weird to me.

    Thanks.

    Reviewed by bjarn at 2017-03-19 16:45
  • 6. guard_name also as a function

    Could it be possible to make $guard_name a property and a static function in the same way Nova does it with 'group' and 'name'? So we can use config('nova.guard')? I'm using a 'web' guard for normal users and a 'back' guard for admin users.

    Reviewed by gerardnll at 2019-09-05 09:13
  • 7. There is no permission named `edit articles` for guard `web`.

    I am having issue when seeding the roles and permissions. I even copy their sample on database seeding here https://github.com/spatie/laravel-permission#database-seeding. I even clear and removed cache before seeding and still I get that error as you can see on this screenshot https://www.screencast.com/t/PAMOsZjS

    Anyone could help?

    Thank you.

    Reviewed by jacktyler2318 at 2017-12-13 17:32
  • 8. ErrorException : Trying to access array offset on value of type null. On fresh laravel installation.

    I can't install the package on my recent laravel project. It works fine on the previous ones. Here is the error I get

    `composer require spatie/laravel-permission Using version ^3.6 for spatie/laravel-permission ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 1 install, 0 updates, 1 removal

    • Removing spatie/laravel-view-components (1.2.0)
    • Installing spatie/laravel-permission (3.6.0): Loading from cache Writing lock file Generating optimized autoload files

    Illuminate\Foundation\ComposerScripts::postAutoloadDump @php artisan package:discover --ansi

    ErrorException : Trying to access array offset on value of type null

    at /home/abdellah/Documents/PROJECTS/Bank/vendor/spatie/laravel-permission/src/PermissionServiceProvider.php:61 57| protected function registerModelBindings() 58| { 59| $config = $this->app->config['permission.models']; 60|

    61| $this->app->bind(PermissionContract::class, $config['permission']); 62| $this->app->bind(RoleContract::class, $config['role']); 63| } 64| 65| protected function registerBladeExtensions()

    Exception trace:

    1 Illuminate\Foundation\Bootstrap\HandleExceptions::handleError() /home/abdellah/Documents/PROJECTS/Bank/vendor/spatie/laravel-permission/src/PermissionServiceProvider.php:61

    2 Spatie\Permission\PermissionServiceProvider::registerModelBindings() /home/abdellah/Documents/PROJECTS/Bank/vendor/spatie/laravel-permission/src/PermissionServiceProvider.php:36

    Please use the argument -v to see more details. Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1

    Installation failed, reverting ./composer.json to its original content.`

    Reviewed by abdellahramadan at 2020-02-15 08:08
  • 9. Question: Multi Tenant

    In a SaaS kind of app, I want the Roles to be tenant specific, meaning:

    Roles for App X | Roles for App Y ------------ | ------------- Owner | Superintendent Worker| All mighty Maintenance| Superman

    Its not only a matter of naming, each role has different permissions, and App X can't see App Y roles and vice versa. Also there can be an infinite number of apps...

    Any suggestion for achieving this? Maybe using guards? Maybe adding a tenant column to the tables? Thanks.

    Reviewed by jonagoldman at 2017-04-26 16:03
  • 10. [Proposal] Role Hierarchy Level (integer)

    Hey all,

    thanks for this awesome package - i really like it as it is quite easy to use. Recently, i stumbled upon a problem, which i thought i could share with you - this might be a contribution for your package.

    Problem

    In my application i have Teams (a User can be in multiple Teams) and Projects (a Project can have multiple Teams). Furthermore, a Team can have a specific Role within a Project. Therefore, one User can have multiple Roles within a Project.

    For now, let us call these Roles Owner, Manager and Member (as they already imply some kind of Hierarchy: Owner > Manager > Member.

    I would like to retrieve the highest (i.e., the role with the most access rights) Role for one specific User within a Project.

    Idea

    I thought it may be possible to enhance the Role table and add an additional level (int, default 0) field to the database. This field would act as some kind of hierarchy.

    In the given example, one could just define Owner (10) > Manager (5) > Member (1). Note that the numbers indicate the level.

    When retrieving all Roles for the User within a Project we would just need to sort by level and we're already set up!

    Furthermore, this idea could be enhanced in order to provide some additional functions to restrict access not only by Role or Permission but also by Level. Think about a method like this hasAtLeastRoleLevel(int level) to check, if the level of the User is higher than - therefore he has access..

    What do you think about this feature? Best

    Reviewed by johannesschobel at 2017-10-17 08:43
  • 11. Laravel Roles and Permissions with parameters

    I am planning on extending a system that helps me mark students off in lab classes of various courses that they are enrolled in. I have a basic version of the system working, but it needs a better permission system.

    I have users and courses. What I want is the ability to have roles such as "Coordinator" and "Grader" but based on a course.

    So a particular user might be a "Grader on Course1" and a "Coordinator on Course2"

    The role of "Grader on Course X" would have underlying permissions of "Can view Course X", "Can Grade Course X" etc. "Coordinator on Course X" might have other permissions such as "Can enroll students on Course X".

    So my roles and permissions are sort of parameterized by courses.

    With spatie/laravel-permission I understand that I can make roles such as Grader and Coordinator (along with the underlying permissions). But that would not allow me to make a particular user a Grader on one course but not all the others.

    Combining this package (spatie/laravel-permission) with Laravels policies I think I get closer. The policies are parameterized by models (i.e., the Course model in my case). But I don't understand how the policies would tie in with the roles and permissions unless they are too parameterized.

    Any ideas on the best way to solve this?

    One way I thought of was to have roles such as "coordinator_course1", "coordinator_course2", "coordinator_course3" ... and permissions such as "can_view_course1", "can_view_course2", "can_view_course3", ... But this feels like a poor choice.

    Any advice would be most welcome.

    Reviewed by liamoreilly at 2019-06-29 07:49
  • 12. Fatal error: Uncaught ReflectionException: Class "config" does not exist

    If I want to adhere to the principle of dependency injection, and add Spatie\Permission\Models\Role to the __construct of any class, I will get an error Fatal error: Uncaught ReflectionException: Class "config" does not exist

    Because the helper config() is not initialized yet at the moment.

    A simple example:

    
    namespace App\Services\Permission;
    
    class PermissionService
    {
        public function __construct(
            private \Spatie\Permission\Models\Role $role,
        ) {
        }
    }
    

    Now in the terminal, try typing a command, for example php artisan cache:clear, and you will get an error. I have a solution, I will offer it in PR ))

    Versions laravel/framework - v8.83.11 spatie/laravel-permission - 5.5.3 PHP 8.0.8 Windows 11

    Reviewed by adiafora at 2022-05-17 06:25
  • 13. Custom primary keys tests(Only tests)

    For avoid breaking this again on the future

    • Complement of #2092

    Also using variables for migrations as starting point for future anonymous migrations support

    protected static $migration;
    protected static $customMigration;
    
    Reviewed by erikn69 at 2022-05-16 14:41
Laravel Users (Roles & Permissions, Devices, Password Hashing, Password History).
Laravel Users (Roles & Permissions, Devices, Password Hashing, Password History).

LARAVEL USERS Roles & Permissions Devices Password Hashing Password History Documentation You can find the detailed documentation here in Laravel User

Apr 20, 2022
Laravel Auth is a Complete Build of Laravel 8 with Email Registration Verification, Social Authentication, User Roles and Permissions, User Profiles, and Admin restricted user management system.
Laravel Auth is a Complete Build of Laravel 8 with Email Registration Verification, Social Authentication, User Roles and Permissions, User Profiles, and Admin restricted user management system.

Laravel Auth is a Complete Build of Laravel 8 with Email Registration Verification, Social Authentication, User Roles and Permissions, User Profiles, and Admin restricted user management system. Built on Bootstrap 4.

May 20, 2022
Tech-Admin is Laravel + Bootstrap Admin Panel With User Management And Access Control based on Roles and Permissions.
Tech-Admin is Laravel + Bootstrap Admin Panel With User Management And Access Control based on Roles and Permissions.

Tech-Admin | Laravel 8 + Bootstrap 4 Tech-Admin is Admin Panel With Preset of Roles, Permissions, ACL, User Management, Profile Management. Features M

May 19, 2022
Handle roles and permissions in your Laravel application

Laratrust (Laravel Package) Version Compatibility Laravel Laratrust 8.x 6.x 7.x 6.x 6.x 6.x 5.6.x - 5.8.x 5.2 5.3.x - 5.5.x 5.1 5.0.x - 5.2.x 4.0. Ins

May 14, 2022
Powerful package for handling roles and permissions in Laravel 5

Roles And Permissions For Laravel 5 Powerful package for handling roles and permissions in Laravel 5 (5.1 and also 5.0). Installation Composer Service

May 24, 2022
Laravel Roles and Permissions

Introduction to Laravel Roles and Permission App Starter Kit Roles and sanctions are a paramount part of many web applications. In project, we have op

Nov 1, 2021
A Powerful package for handling roles and permissions in Laravel with GUI.
A Powerful package for handling roles and permissions in Laravel with GUI.

Laravel Roles A Powerful package for handling roles and permissions in Laravel. Supports Laravel 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 6.0, 7.0, and 8.0+. Tab

May 21, 2022
This is a lightweight package that allows you assign roles and permissions to any Laravel model, or on a pivot table (many to many relationship).
This is a lightweight package that allows you assign roles and permissions to any Laravel model, or on a pivot table (many to many relationship).

Simple Laravel roles and permissions Introduction This package allows you to assign roles and permissions to any laravel model, or on a pivot table (m

May 6, 2022
Roles & Permissions for Laravel 8 / 7 / 6 / 5

Defender Defender is an Access Control List (ACL) Solution for Laravel 5 / 6 / 7 (single auth). (Not compatible with multi-auth) With security and usa

Apr 28, 2022
PermissionsMakr is a Laravel package that will help any developer to easily manage the system's users permissions

PermissionsMakr is a Laravel package that will help any developer to easily manage the system's users permissions

Nov 30, 2021
Eloquent roles and abilities.
Eloquent roles and abilities.

Bouncer Bouncer is an elegant, framework-agnostic approach to managing roles and abilities for any app using Eloquent models. Table of Contents Click

May 15, 2022
Proyecto para aprender a utilizar privilegios (roles y permisos) con CRUDBooster

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

May 9, 2022
Role-based Permissions for Laravel 5

ENTRUST (Laravel 5 Package) Entrust is a succinct and flexible way to add Role-based Permissions to Laravel 5. If you are looking for the Laravel 4 ve

May 12, 2022
Light-weight role-based permissions system for Laravel 6+ built in Auth system.

Kodeine/Laravel-ACL Laravel ACL adds role based permissions to built in Auth System of Laravel 8.0+. ACL middleware protects routes and even crud cont

Apr 29, 2022
Manage authorization with granular role-based permissions in your Laravel Apps.
Manage authorization with granular role-based permissions in your Laravel Apps.

Governor For Laravel Manage authorization with granular role-based permissions in your Laravel apps. Goal Provide a simple method of managing ACL in a

Apr 21, 2022
Laravel mongodb permissions

Laravel mongodb permissions

May 10, 2022
this is a semester project using Laravel, this app allow user to keep and shear their note with other users.

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Dec 24, 2021
EAuth extension allows to authenticate users by the OpenID, OAuth 1.0 and OAuth 2.0 providers

EAuth extension allows to authenticate users with accounts on other websites. Supported protocols: OpenID, OAuth 1.0 and OAuth 2.0.

Apr 22, 2022
Laravel package to easily login as other users during development.
Laravel package to easily login as other users during development.

A Laravel 5.4 utility package to enable developers to log in as other users during development. Installation To install the package, simply follow the

May 16, 2022