Wednesday, November 15, 2017

Gates and Policies in Laravel

Gates and Policies in Laravel

Today, we're going to discuss the authorization system of the Laravel web framework. The Laravel framework implements authorization in the form of gates and policies. After an introduction to gates and policies, I'll demonstrate the concepts by implementing a custom example.

I assume that you're already aware of the built-in Laravel authentication system as that's something essential in order to understand the concept of authorization. Obviously, the authorization system works in conjunction with the authentication system in order to identify the legitimate user session.

If you're not aware of the Laravel authentication system, I would highly recommend going through the official documentation, which provides you with hands-on insight into the subject.

Laravel's Approach to Authorization

By now, you should already know that the Laravel authorization system comes in two flavors—gates and policies. Although it may sound like a complicated affair, I would say it's pretty easy to implement it once you get the hang of it!

Gates allow you to define an authorization rule using a simple closure-based approach. In other words, when you want to authorize an action that's not related to any specific model, the gate is the perfect place to implement that logic.

Let's have a quick look at what gate-based authorization looks like:

The above snippet defines the authorization rule update-post that you could call from anywhere in your application.

On the other hand, you should use policies when you want to group the authorization logic of any model. For example, let's say you have a Post model in your application, and you want to authorize the CRUD actions of that model. In that case, it's the policy that you need to implement.

As you can see, it's a pretty simple policy class that defines the authorization for the CRUD actions of the Post model.

So that was an introduction to gates and policies in Laravel. From the next section onwards, we'll go through a practical demonstration of each element.

Gates

In this section, we'll see a real-world example to understand the concept of gates.

More often than not, you end up looking at the Laravel service provider when you need to register a component or a service. Following that convention, let's go ahead and define our custom gate in the app/Providers/AuthServiceProvider.php as shown in the following snippet.

In the boot method, we've defined our custom gate:

While defining a gate, it takes a closure that returns either TRUE or FALSE based on the authorization logic that's defined in the gate definition. Apart from the closure function, there are other ways you could define gates.

For example, the following gate definition calls the controller action instead of the closure function.

Now, let's go ahead and add a custom route so that we can go through a demonstration of how gate-based authorization works. In the routes file routes/web.php, let's add the following route.

Let's create an associated controller file app/Http/Controllers/PostController.php as well.

In most cases, you'll end up using either the allows or denies method of the Gate facade to authorize a certain action. In our example above, we've used the allows method to check if the current user is able to perform the update-post action.

Users with sharp eyes would have noticed that we've only passed the second argument $post to the closure. The first argument, the current logged-in user, is automatically injected by the Gate facade.

So that's how you're supposed to use gates to authorize actions in your Laravel application. The next section is all about how to use policies, should you wish to implement authorization for your models.

Policies

As we discussed earlier, when you want to logically group your authorization actions for any particular model or resource, it's the policy you're looking for.

In this section, we'll create a policy for the Post model that will be used to authorize all the CRUD actions. I assume that you've already implemented the Post model in your application; otherwise, something similar will do.

The Laravel artisan command is your best friend when it comes to creating stubbed code. You can use the following artisan command to create a policy for the Post model.

As you can see, we've supplied the --model=Post argument so that it creates all the CRUD methods. In the absence of that, it'll create a blank Policy class. You can locate the newly created Policy class at app/Policies/PostPolicy.php.

Let's replace it with the following code.

To be able to use our Policy class, we need to register it using the Laravel service provider as shown in the following snippet.

We've added the mapping of our Policy in the $policies property. It tells Laravel to call the corresponding policy method to authorize the CRUD action.

You also need to register the policies using the registerPolicies method, as we've done in the boot method.

Moving further, let's create a couple of custom routes in the routes/web.php file so that we can test our Policy methods there.

Finally, let's create an associated controller at app/Http/Controllers/PostController.php.

There are different ways you could authorize your actions using Policies. In our example above, we’ve used the User model to authorize our Post model actions.

The User model provides two useful methods for authorization purposes—can and cant. The can method is used to check if the current user is able to execute a certain action. And the counterpart of the can method, the cant method, is used to determine the inability of the action execution.

Let’s grab the snippet of the view method from the controller to see what exactly it does.

Firstly, we load the currently logged-in user, which gives us the object of the User model. Next, we load an example post using the Post model.

Moving ahead, we’ve used the can method of the User model to authorize the view action of the Post model. The first argument of the can method is the action name that you want to authorize, and the second argument is the model object that you want to get authorized against.

That was a demonstration of how to use the User model to authorize the actions using policies. Alternatively, you could use the Controller Helper as well, if you’re in the controller while authorizing a certain action.

As you can see, you don’t need to load the User model if you use the Controller Helper.

So that was the concept of policies at your disposal, and it’s really handy while authorizing a model or a resource as it allows you to group the authorization logic in one place.

Just make sure that you don’t use gates and policies altogether for the same actions of the Model, otherwise it’ll create issues. That’s it from my side for today, and I’ll call it a day!

Conclusion

Today, it was Laravel authorization that took the center stage in my article. At the beginning of the article, I introduced the main elements of Laravel authorization, gates and policies.

Following that, we went through creating our custom gate and policy to see how it works in the real world. I hope you’ve enjoyed the article and learned something useful in the context of Laravel.

For those of you who are either just getting started with Laravel or looking to expand your knowledge, site, or application with extensions, we have a variety of things you can study on Envato Market.

As always, I would love to hear from you in the form of comments using the feed below!


No comments:

Post a Comment