I am writing for personal use an extension for Laravel to control access to the site.
Did not use any ready-made solutions.
I follow the logic.
First I will describe what I have invented, then the question.

He doubted what to bind to: the URL or the methods in the controllers.Stopped on methods in controllers.

What actions may need to be protected: CRUD.Any actions on the site fall under this set.In some cases, not the whole set will be used, but nonetheless.For example.



All actions that need to be protected will be stored in the permissions table.Records of the type ClassName.methodName are stored there.In order to allow the user to some kind of protected actions, they need to be combined into roles.These roles are stored in the role table.Roles and permissions tables have many-to-many relationships.This will allow you to create both standard roles(admin, user, etc.) and personal ones if necessary(vasya, etc.).The user can only be assigned a role, but must first be created.Since the extension is installed on the existing Laravel authorization/registration system, then by default each user will be assigned the only initially existing default role, which will prohibit all actions for the user(or you can configure a number of general allowed for all).That is, in order for a user to have the ability to perform prohibited actions, he needs to create a role, add permissions to this role, and assign this role to the user.
Thus, the problem of blocking certain actions in logic is solved.
In order to designate that the execution of an action depends on the role, it is enough to call the ACL :: hasPermission() in the required RESTfull method.If the user does not have an action right, an error will be displayed.If it does, then nothing will happen.There is nothing to pass to the method.Since permissions in the table of permissions in the form of ClassName.methodName, then hasPermission will take __CLASS__, __METHOD__ compare them with the roles in the current session(when authorizing a user, the roles will be added to the session so as not to pull from the database every time).
Now the problem.One more is left.Depending on the role, it may be necessary to change some parts of the view.To bind to role id or name is a bad option, because they are fickle.At any moment they can retire, change.But permissions are relatively constant.How is it better to shape the content depending on the user's permissions?

2 Answers 2

I used the approach taken from CanCan gemfrom RubyOnRails.

The idea is this: define trait Ability and add it to the User class.This trait itself has a can method that allows/denies certain actions:

<?Php

trait Ability
{
    public function can($verb, $noun)
    {
        $class=is_string($noun)? $noun: get_class($noun);
        if(is_callable([this,"canManage $class"]))
        {
            $this->{"canManage $class"}($verb, $noun);
        } else {
             $this->fallback($verb, $noun);
        }
    }

    public function canManageUser($verb, $noun)
    {
        switch($verb) {
            case'create':
                return true;
            case'edit':
                if($this->isAdmin()) return true;
                if($noun->id == $this->id) return true;
                break;
            case'delete':
            case'destroy':
                if($noun->id == $this->id) return false;
                break;
        }
        return $this->fallback($verb, $noun);
    }

    public function fallback($verb, $noun)
    {
        if($this->isAdmin()) return true;
        return false;
    }

    public function isAdmin()
    {
        return $this->role == self :: ADMIN;
    }
}


Thus, we isolate the semantics of roles in one particular place, and determine permissions not at the level of the Entity class, but at the level of a specific entity, which is much more flexible.

As for the use in the view, no problems:
@ if(Auth :: user()&Auth :: user() ->can('edit', $page))
<form></form>
@endif
@if(Auth :: user()&Auth :: user() ->can('create','Page'))
<a href="#">Add a page</a>
@endif
And what do you draw the scheme? Very nice looking
  • :) MindJet – Vast Vole Feb 22 '14 at 11:09