In case you didn’t know, Laravel includes authorization mechanisms to gracefully authorize an authenticated over a particular action or resource.

As a reminder, here is the basics: Gates can act over any logic, like authorizing a user to see the Administration Dashboard if he is an “admin”. Meanwhile, Policies act exclusively over the CRUD operations of a resource: create, retrieve, update and delete. For example, letting only the Article’s author to update his own publication, while denying the rest of the users.

To declare them, you usually go to your AuthServiceProvider and define every Gate and Policy your application uses. You can do it from the array (for the Policies), and even create your own array for the Gates if you have many. Otherwise it’s safe to register them manually as the documentation says.

In this example I just made something convenient, since I have a lot of Gates and Policies.

Okay, we have our Policies and Gates defined. If you see the $gates array, there are a lot of them defined as see-something . Depending on the “role” of the User, he can see the dashboard, the gallery and the system configuration. These are only used in their particular controllers.

Welp, we don’t need to define every Gate in the AuthServiceProvider . While it’s recommended to, since it allows you to centralize the authorization making it available globally, sometimes it’s better to declare it in your controller and call it a day, specially if it’s only a simple Closure based gate you only use one time.

Yeah, just put it in the constructor

In the same way you declare a middleware in your Controller, you can use the Gate facade to define a Gate — yes, sounds weird. When the Controller is instanced, the __construct method will run before anything else, and since we’re using Automatic Injection, the Gate will be automatically resolved so we can use it inside the method and define our Gate.

Then, in your method, you just proceed as normal.

This is just a simple example, but allows to slim down your AuthServiceProvider if you have multiple Gates, or you use a particular Gate in only one Controller like I’m doing in the example.

Additionally, you can set the authorization middleware to only work on certain methods, or exclude them.

$this->middleware('can:see-dashboard')->except('otherMethod');

The exclusion is particularly handy if your Gate expect optional arguments. Since we can’t add the parameters before hitting the method logic, excluding that method from the middleware will allow you to put the parameters while using the authorization helper directly.

public function changeOwner(Request $request, Article $article)

{

$this->authorize('can-change-owner', $article); // ... Change ownerage of the Article

}

When *NOT* to use this approach

As you are guessing, the Gate lives inside the Controller. This means that the Gate will only work inside the Controller, decentralizing it completely.

If you expect to call the same authorization logic from multiple points, like in vies, you may want to use the classic way to define the Gates, since they will be available at boot time and globally available inside the application: Controllers, Console, inside Jobs, Listeners, you name it.

This means, you can also use the Gate::authorizeForUser() , and issue manually the user that should be authorized (or not) for that particular action.

No need to overthink Gates in your application.