تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Need Granular Access Control0:00

Using roles to control how users can or can't access certain parts of the application is very useful, but there are times when you need more granular control. Like, for example, I am signed in as the Author, and Authors are only supposed to be able to edit their own articles. They cannot edit anyone else's articles. And of course, our application is currently set up to do that, because several episodes ago, we defined a gate. It is the ManageArticles gate, and if the user has the admin or the editor role, then they can edit. Otherwise, they have to have the author role, and the userId has to match the article's authorId. And there's nothing wrong with using a gate. In fact, this is exactly what gates are defined for, to give us a more granular access control. However, Laravel has another mechanism. It's very similar.

Introducing Laravel Policies0:49

In fact, this is exactly what gates are defined for, to give us a more granular access control. However, Laravel has another mechanism. It's very similar. And in fact, you're going to see just how similar it is. And it's called a policy. So we are going to make a policy. Let's call it ArticlePolicy. And a policy is nothing more than a class. It gives us an area that we can define the access rules for a particular model or resource. So by creating an ArticlePolicy, we are essentially saying that all of our access rules for articles are going to be inside of this class. Meaning that we don't have to create a bunch of gates in order to control access.

Defining Update Authorization1:20

So by creating an ArticlePolicy, we are essentially saying that all of our access rules for articles are going to be inside of this class. Meaning that we don't have to create a bunch of gates in order to control access. We will just use this ArticlePolicy and store all of the rules for accessing or working with articles here. So all we need to do is define a method. The method name is arbitrary. We can call it whatever we want, but it needs to be, you know, something meaningful. Like for example, we want to update an article. So we can call our method update. We automatically get a $user supplied for us, and we get the $article that we want to work with. So all we really need to do now is check if the $user has any role.

We automatically get a User supplied for us, and we get the Article that we want to work with. So all we really need to do now is check if the user has any role. And if they are an admin or an editor, then we will simply return true. Otherwise, the user has to be an author. And the userId has to equal the article's authorId. So it's practically the same exact logic that we had for our ManageArticles gate, except that now it is defined inside of this ArticlePolicy. And I believe we used that gate in two different places. The first was the ArticleUpdateRequest. So here, where we checked if the user is allowed to manage articles, we can just change that to Update.

Replacing Gate Checks2:38

The first was the ArticleUpdateRequest. So here, where we checked if the user is allowed to manage articles, we can just change that to update. And that's still going to work like it did before. Inside of the index view for our articles, we used the can directive here. Can the user manage articles? Well, now it's simply, can the user update the article? And then everything is going to work as it did before. So then the question becomes, how does Laravel know to use our ArticlePolicy in these two places? And it's actually quite simple. Because our policy follows the conventions.

Policy Auto-Registration Conventions3:10

And it's actually quite simple. Because our policy follows the conventions. Our policy is defined inside of the app/Policies directory. And our policy class name is called Article, which is a model, followed by the policy suffix. So therefore, behind the scenes, Laravel is going to automatically register this Article Policy class, and it's going to bind it to the article model. So now, whenever we check really any policy involving an article, like here, we pass in the article, Laravel knows to use the ArticlePoliciesUpdate method to check that policy. Now, we can create a policy using, well, it's basically the same command, but we just need to add another option to it.

Generating a Policy via Artisan3:50

Now, we can create a policy using, well, it's basically the same command, but we just need to add another option to it. Because when it comes to defining policies, you'll find that there are several actions that you will want to check for. So we will once again make the policy, we'll call it ArticlePolicy. But then, we'll have --model, and we will tell it Article. This is going to create another ArticlePolicy class, but now it's going to predefine some methods. So we can see that there's a viewAny, a view, create, update, delete, and so on. But once again, remember that these method names are arbitrary. You can come in here and you can delete everything in here and start over from scratch. Or if you want to delete the methods that you don't need, you can do that as well.

You can come in here and you can delete everything in here and start over from scratch. Or if you want to delete the methods that you don't need, you can do that as well. In our case, I'm going to keep everything and we're going to use this update method once again. But everything is going to work the same as it did before. It's just that now we have a class with predefined methods that we can use if we want to. And once again, because our ArticlePolicy follows the convention, we don't have to register the policy. However, if it didn't, we could go to the app ServiceProvider and we could register our policy here. We would just need to use the Gate facade. To do so, we would call the policy method. We would pass in the model, which in our case is our Article class.

To do so, we would call the policy method. We would pass in the model, which in our case is our Article class. Then we pass in the policy for that class. So we would essentially be binding this ArticlePolicy for this article model. But, you know, once again, this is automatically done for us because our policy follows conventions. So we don't have to do that. So now the question becomes, why use policies? Why not define just a bunch of gates? Which, you know, technically you can do that. However, the policy gives us a place that we can organize all of our access rules for a given model or a given resource.

Which, you know, technically you can do that. However, the policy gives us a place that we can organize all of our access rules for a given model or a given resource. So instead of defining a bunch of gates working with articles, we can just create our policy, define our access rules there, and everything is nice and neatly organized. Ultimately, it's kind of the same thing. It's just organized better. But we're not done with policies. We'll continue looking at them in the next episode.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟