Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

toniperic's avatar

[L5] Roles and permissions

Building a CMS for my company in Laravel 5, which makes me so happy.

We are supposed to have different roles, such as "developer", "boss", "sales", "client" etc, and each role should have some set of permissions (to access a certain route).

What would be the best way to accomplish this? I'm talking about both code and database structure.

0 likes
20 replies
jekinney's avatar

Easily build your own with a few tables and methods. Not going to type it all out here but Jeffery has a video about roles and you can easily add permissions to each role and run a few methods to check if a user has permissions.

Basically my suggestion is:

Roles table, role_user pivot to assign a user to a role, Permissions table and a permission_role pivot to assign permissions to a role.

If your developing apps, a role and permissions should be a snap.

jekinney's avatar

@ kai_desu

Awesome!!! Looking at it now.

1 like
michaeldyrynda's avatar

I've used this blog post as a basis for putting something simple together for a personal project. You might need to tweak it a little for L5.

Sometimes you don't need the complexity or overhead offered by a prewritten package.

1 like
jekinney's avatar

Sentry is written for PHP and not specifically for Laravel. I personally find it messy and most of it you will never use. Just my 1/2 cent.

2 likes
InFloW's avatar

I initially used Sentry but opted to later switch to just using my own. The way things are laid out it's very easy to create your own. It's a simple as a single middlware and the key to it is is knowing the following:

$route = $request->route();
$action = $route->getAction();

If you dd() $action you'll see it has your route names. So you could just do something like maybe:

if ( ! $request->user()->hasRoute($action['as']))
{
    return response('Unauthorized.', 401);
}
return $next($request);

Add the method on the users model. For the database structure it'll depend on how you intend on laying it out. Do you want users to have a single role or multiple roles. This post outlines a decent database structure: https://laracasts.com/discuss/channels/requests/role-based-resources-management . Only thing you might change is the actions table would instead just have:

name

description

route

1 like
toniperic's avatar

Thanks guys for all of your help, this will come in handy for lots of people.

Now, what are your advices on building an ACL system in Laravel? Simply put in an example: I have a navigation with three links - link1, link2 and link3. What if you wanted to specify for every user in the system which of those three links the user could see? Ie:

  • user1 could see only link 1
  • user2 could see link1 and link2
  • user3 could see link1, link2 and link3
  • user4 could see link1 and link3 etc.

Would you go about it the same way as with the roles system? I very much want to learn how to build this on my own so I'd like to follow best practices as much as possible.

michaeldyrynda's avatar

Just wrap the items in the navigation in a permission check:

<nav>
    <ul>
    @if ( User::acl()->has('permission1') )
        <li><a href="#">Link 1</a>
    @endif
    @if ( User::acl()->has('permission2') )
        <li><a href="#">Link 2</a>
    @endif
    @if ( User::acl()->has('permission3') )
        <li><a href="#">Link 3</a>
    @endif
    </ul>
</nav>

Switch out the permission check for however you've implement that functionality. You might put the menu in a view composer and drop the needed permission in there, then just check using the key on your menu collection.

Edit: Remember, your user is granted permission to access things, they're not assigned things they have access to.

1 like
toniperic's avatar

@deringer kudos! That seemed very easy for me too, thought I was wrong and there were other approaches. Many thanks!

michaeldyrynda's avatar

@toniperic There's almost always other approaches, it's up to you to determine what works best for you. One day that will change, and then you can refactor!

Don't get caught up in what's better or the "right way", do what works best for you and revise it as your knowledge increases.

1 like
cgrossde's avatar

I implemented a permission module for Laravel 5: https://github.com/cgrossde/Laraguard (enforcing permissions on controllers/methods) It works great in conjunction with https://github.com/caffeinated/shinobi or https://github.com/romanbican/roles (storing roles and permissions of users)

Adds a permission system to Laravel 5 using the new integrated authentication mechanism. Instead of protecting routes, it protects the controller and its methods. This way you do not expose protected functionality if you forgot to protect a certain route. Controllers are protected with a simple syntax: ControllerName@MethodName. If you have a ClientController.php and want to add a permission called client.edit you would do something like this:

client.edit:
  - Client@edit
  - Client@update

Laraguard also supports * if you want to allow all methods or all controllers:

client.admin:
  - Client@*

site.admin:
  - "*@*"

Should be quite easy to use ;) If you use roles or not is entirely up to you.

cgrossde's avatar

Nice package, works great together with Laraguard. I added a link of it to the README ;)

yassin98010's avatar

@cgrossde plz what do you meen bye this : " If you have a ClientController.php and want to add a permission called client.edit you would do something like this:

client.edit:

I want to test user acces betwwen 2 view or 3 views how should i do ? thnks

Please or to participate in this conversation.