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

Move to ArticlePolicy0:00

Now that we have an ArticlePolicy, I want to start using that to define all of our access controls, at least as far as working with articles are concerned. So for our articles, I want to start to transition away from using roles, at least as far as the middleware and the directive is concerned. I don't want to get away from roles just yet, because there are still some places where that's all that we need, just is a User in a given role. But when it comes to working with articles, we are seeing that in some cases we need some granular control, and there wasn't a return statement there for the update method inside of the ArticlePolicy. So I don't know why we didn't get an error in the previous episode, but we should have.

of the article policy. So I don't know why we didn't get an error in the previous episode, but we should have. That's fixed now. My bad. All right, so we have this article policy, and the reason why I want to start using this is to just keep all of our authorization logic here. And of course, inside of the ArticleUpdateRequest, we are using that policy. But this is only for when the edit form is submitted. Right now, there is nothing that prevents a user from going to the edit form of an Article that they did not write.

Protect Edit Form Access1:11

Right now, there is nothing that prevents a user from going to the edit form of an article that they did not write. So I am signed in as the author. This is an article written by the AuthorEditor, and we can come here. But of course, if we attempt to actually submit this form, we see that it is not authorized. But I don't even want the user to get this far. So that means we need to do some things inside of the edit method in the ArticlesController. And there are several different ways that we could do this. The first and probably the most straightforward thing to do is to just get the User so that we can call the cannot method.

The first and probably the most straightforward thing to do is to just get the user so that we can call the cannot method. So basically, if the user cannot update this particular article, then we will abort the whole thing. So that now in the browser, if we attempt to get to this form, we see that it is forbidden. And that's perfectly fine. But I think that we can get away with using something other than auth user. And in fact, we can because inside of the authorized method for our ArticleUpdateRequest, we are using the Gate facade. And here we are using the allows method.

Gate Denies vs Allows2:10

we are using the Gate facade. And here we are using the allows method. So we could kind of do the same thing here, except that instead of calling allows, we will call the denies method. It's essentially the exact opposite of the allows. It returns true if the user is denied access to update this particular article. So back in the browser, we can refresh and we see the same exact result. And I personally like this approach because it's easier to read, at least in my opinion. However, we could take this a step further and we could not have an if statement at all because the Gate facade has a method called authorize.

Using Gate Authorize2:43

However, we could take this a step further and we could not have an if statement at all because the Gate facade has a method called authorize. We can specify the ability that we want to check for, update in this case, and the article that we want to work with. And this is going to check if the User is authorized to update that article, in which case it's not authorized. So whenever we refresh, we see that this has changed. This action is unauthorized. So now we don't even have to use an if statement. The authorize method will handle all of that for us.

So now we don't even have to use an if statement. The authorized method will handle all of that for us. If the user is authorized to update, then fine, everything works just as it should. If the user is not authorized, then they are automatically told, hey, you're not authorized to do that. And I personally like that approach because it's a lot cleaner, at least in my opinion. But we can also make this a little bit more flexible by not returning a Boolean value, but returning an AccessResponse. Now this is not an HTTP response. This is an AccessResponse, in which case we would need to change this so that instead

Return AccessResponse Messages3:43

Now this is not an HTTP response. This is an access response, in which case we would need to change this so that instead of returning true, if the user can update an article, we return allow. And then of course we need to change the return statement down here. If the user has the author role and they are the actual author, then yes, we still want to return response allow. Otherwise, we can return response deny. And the great thing about this approach is that we can now supply a custom message. We can say that you do not own this article. In which case, whenever we refresh this in the browser, we will see that custom message.

We can say that you do not own this article. In which case, whenever we refresh this in the browser, we will see that custom message. And I guess we don't need that period. So let's get rid of that. However, by taking this approach, it is going to return a different response, at least as far as what's viewed in the browser whenever the edit form is actually submitted. So let's do this. Let's comment out this call to the authorized method. And in the browser, let's attempt to edit this article. We of course see that this action is unauthorized, but now I want to display this custom message.

And in the browser, let's attempt to edit this Article. We of course see that this action is unauthorized, but now I want to display this custom message instead. And we can do that, but we will need to change the authorize method inside of the ArticleUpdateRequest class. So we still need the Article, but now we need to know what kind of response we get. And to do that, we can use the inspect method on the Gate. This is going to return a response. If the response is allowed, then everything is fine. We can return true here.

If the response is allowed, then everything is fine. We can return true here. But if the response is denied, then we can return an AuthorizationException with our custom message. So all we need to do is check. If the response is allowed, then we will simply return true because we need to return a Boolean value here. However, if we make it past that if statement, then authorization failed. In which case, we'll just throw a new AuthorizationException and we will pass in the message from our response.

In which case, we'll just throw a new AuthorizationException and we will pass in the message from our response. We can get rid of this call to the allows method because we have essentially checked already if the User can update the Article. So now back in the browser, we can refresh to resubmit the form and we see the custom message. You do not own this article, which means we can go back to the ArticlesController. Let's uncomment this line to authorize the user to update the article. And so now not only will the User get this message if they attempt to actually edit the article, but they will also get the same response if they try to edit or access the edit form.

Respond With 404 Option6:07

And so now not only will the User get this message if they attempt to actually edit the Article, but they will also get the same response if they try to edit or access the edit form for that Article. But there's also a pattern to where instead of returning a 403, we would simply return a 404. Because as far as the author is concerned, that Article doesn't exist. It at least doesn't exist for them. So we could return this deny as not found, which means that whenever the User attempts to access the edit form for that Article, they get a 404. That of course breaks the consistency between viewing the edit form and actually submitting.

to access the edit form for that article, they get a 404. That of course breaks the consistency between viewing the edit form and actually submitting the edit form. In which case, all we need to do is throw a different exception. We could say the ModelNotFoundException. We don't need to supply a message there. And so now it doesn't matter if the user tries to access the edit form or submit the edit form, they receive a 404. So there are different ways that we can write our policy methods. We can simply return a boolean value, or we can return responses.

So there are different ways that we can write our policy methods. We can simply return a Boolean value, or we can return responses. And there's no right or wrong way of doing it. It's really up to you and how you want those methods to behave. And we also have different ways that we can check if the user is authorized to perform a particular ability. We can use methods on the user model, or we can use methods on the Gate facade. Once again, it's really up to you and how you want to implement and use those policies.

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