Determining whether or not a user is allowed to perform a certain action is an important aspect of building a CMS. It provides users with ownership of their data, preventing other users from performing CRUD functionality on data that should be hidden from them. This is more commonly referred to as authorization. Laravel accomplishes this job by using gates and/or policies. This blog entry will cover how gates are used in the KANBAN application. Only one example will be covered as the process is the same for creating different gates for different actions.
Workflow
There are multiple steps involved when attempting to secure actions. There are shortcuts that can be taken to reduce the number of these steps however in doing so the applications logic becomes less manageable as some methods could become 'fat'. This makes the code harder to understand.
Initially the developer should create a security policy, these are stored in app_route/app/Policies and follow the xPolicy.php convention where x is the name of the policy. These policies are then mapped to gates that are defined in the apps AuthServiceProvider.php file located in app_route/app/Providers.
Policies can be used in other ways however I found that using gates worked more consistently. There may have been something I misunderstood when attempting to solely use policies, something I will need to look over again in future projects. For this reason I stuck to using gates although the way they are constructed and written seems less preferable over policies, however this is just a preference.
Once these gates have been mapped they can be used either in an application Model or Controller class to control and limit access to certain actions / resources.
Creating Policies
Policies are the rulesets that determine whether or not a certain actor can perform a given action. For this example I will cover the creation of tasks in the application.
This creates a file named TaskPolicy.php in app/Policies/TaskPolicy.php.
The following image contains an example of two actions and their rulesets.
In order to pass the view expression the user must be equal to the owner of the board that the task is contained within. As for the create rule, to pass this expression the column is passed in as an argument, and the owner of the board for that given column must also equal the authenticated user attempting to create the task. This also file contains rules for updating and deleting however I have left them out of the example for brevity.
Mapping Policy Actions To Gates
Once a policy has been created it is time to map the methods in the policy to a gate, which can be done using callback methods. This can be done by using the Gate::define method.
When solely using gates the policies array need not be used however I have included it anyway. I found that the $request->user()->can and $request->user()->cannot() methods did not work every time as I intended so I opted to use gates as previously mentioned.
Applying & Using The Registered Policies
Now that the policies have been registered successfully by the application they can easily be used throughout any controllers that require securing. The following image shows the create-task gate contained within the TaskControllers store method. The condition must return true for the logic to progress "pass through to your gate(s)". If the condition does not return true then an HTTP response is sent to the client with a status code of 401 unauthorised. Concluding Remarks
There are multiple ways to secure access, and the route that the developer takes seems to be up to them as they are two different styles to accomplish the same goal. Policies I believe provide a more granular approach that can be tied to a specific model, gates look to be slightly more flexible and can be placed anywhere.
Security is a large topic where there are a lot of ways things can go wrong. I will definitely need to read more into how Laravels security works and work through more tutorials online to get a better understanding as I was unable to get policies to work as I wanted to. Despite this I successfully managed to get gates to work as intended.
I am currently working on a project using React & Apollo Server for my final year honours project and I have implemented authentication and authorization in that, however doing so was significantly more challenging. Despite this it did force me to learn how these systems work in a more fundamental way. Laravel does a great job at making implementing authorization easy however I admittedly did not learn much about how that actually works, due to its abstraction, which would have been nice although the cost of that would have been more time taken.
Laravel provides an easy means to implement security that feels safe to trust. When developing an application that requires authentication and authorisation Laravel is definitely a strong choice.
Comments
Post a Comment