I use laravel Authentication, but for gates and policies, I wrote a helper class to check if a user has or does not have access. There is nothing in the docs that prevents you from writing such a class to better organize this stuff.
Every secure method has to be checked one way or the other.
RBAC became a little clearer to me when I pictured it like this.
Pretend you are in a large industrial complex with many rooms and many doors. Depending on access level, security badges are required.
But the badges are different depending on persons security clearance.
They have a maintenance department accounting department Human Resources, executives (admins), scientist, all different levels of employees.
So a user (person) is walking through and each door either user can or cannot enter.
And me I like looking at each controller method the same way, the logged in user can or cannot do that method.
And of course the other part of RBAC, is to allow a user to see and edit their own data while disallowing other uses.
Even Jeffrey in one of his videos mentioned setting this stuff up can be tricky at first but once learned gets easier.
So I look at it like:
// Bob has roles assigned admin and bookkeeper
// A method in controller Bob wants to access
// This method (function) requires the role to be bookkeeper
// YOU NEED TO PROGRAM IN (However you need to)
// Is bookkeeper one of Bobs roles.
if bookkeeper matches one of Bobs stored roles
allow access
otherwise
redirect where ever
And as far as a user seeing and editing their own data, see this link:
https://laracasts.com/discuss/channels/laravel/using-laravel-policy-to-filter-eloquent-query
And here are some other general links:
https://laracasts.com/discuss/channels/laravel/multi-auth-on-laravel-using-the-same-login-page
https://laracasts.com/discuss/channels/code-review/multi-auth-with-different-login-forms
https://laracasts.com/discuss/channels/laravel/permissions-and-roles
https://laracasts.com/discuss/channels/laravel/duel-roles
The following
I do not condone, or am I saying to do anything this way, but it works for me.
Instead of the code required for gates and policies, I handle at method level. I ensure user is logged in via the auth group in routing.
I have in a custom class a method:
public static function chkRole($role = null)
{
$userrole = Auth::user()->role;
$checkrole = explode(',', $userrole);
if (in_array($role, $checkrole)) {
return true;
}
return false;
}
I store roles in a field in users table like:
role
admin,bkeep,user
bkeep short for bookkeeper.
And for a method
public function someMethod()
{
if (!ChkAuth::chkRole('admin')) {
return redirect('where_ever'); // or whatever you need to do.
}
// rest of method
Again
I am in no way saying how to implement your RBAC, rather just showing how it works using this.
Above could have been one line of code, but a redirect isn't allowed in a ternary statement.
Also if a whole controller needs a certain role, just one check in the construct method is needed.
In the case of differentiating an admin vs user to determine what can be viewed in query results, and allowing a user to view or edit their own data, is at query level as in one of the links above.
That's where Auth::user()->id comes in. It is the key to the user only seeing what they are supposed to see in a query.