Laravel

Authorization

Introduction#

Laravel provides a simple way to authorise user actions on specific resources. With Authorization, you can selectively allow users access to certain resources while denying access to others. Laravel provides a simple API for managing user authorizations by using Gates and Policies. Gates provide a simple closure based approach to authorisation using the AuthServiceProvider while Policies allow you to organise authorisation logic around models using classes.

Using Gates

Gates are closures that determine if a user is allowed to perform a certain action on a resource. Gates are typically defined in the boot method of AuthServiceProvider and succinctly named to reflect what it’s doing. An example of a gate that allows only premium users to view some content will look like this:

Gate::define('view-content', function ($user, $content){
    return $user->isSubscribedTo($content->id);
});

A Gate always receives a user instance as the first argument, you don’t need to pass it when using the gate, and may optionally receive additional arguments such as the eloquent model in concern.

Authorizing Actions with Gates

To use the example above on a blade template to hide content from the user, you would typically do something like this:

@can('view-content', $content)
 <! -- content here -->
@endcan

To completely prevent navigation to the content, you can do the following in your controller:

if(Gate::allows('view-content', $content)){
    /* user can view the content */
}

        OR

if(Gate::denies('view-content', $content)){
    /* user cannot view content */
}

Note: You are not required to pass the currently authenticated user to these method, Laravel takes care of that for you.

Policies

Policies are classes that help you organise authorisation logic around a model resource. Using our previous example, we might have a ContentPolicy that manages user access to the Content model.

To make ContentPolicy, laravel provides an artisan command. Simply run

php artisan make:policy ContentPolicy

This will make an empty policy class and place in app/Policies folder. If the folder does not exist, Laravel will create it and place the class inside.

Once created, policies need to be registered to help Laravel know which policies to use when authorising actions on models. Laravel’s AuthServiceProvider, which comes with all fresh Laravel installations, has a policies property which maps your eloquent models to their authorisation policies. All you need to do add the mapping to the array.

protected $policies = [
    Content::class => ContentPolicy::class,
 ];

Writing Policies

Writing Policies follows much the same pattern as writing Gates. The content permission gate can be rewritten as a Policy like this:

function view($user, $content)
{
    return $user->isSubscribedTo($content->id);
}

Policies can contain more methods as needed to take care of all authorisation cases for a model.

Authorizing Actions with Policies

Via The User model

The Laravel User model contains two methods that help with authorisations using Policies; can and can't. These two can be used to determine if a user has authorisation or not on a model respectively.

To check if a user can view a content or not, you can do the following:

if($user->can('view', $content)){
    /* user can view content */
}

        OR

if($user->cant('view', $content)){
    /* user cannot view content */
}

Via Middleware

Route::get('/contents/{id}, function(Content $content){
    /* user can view content */
})->middleware('can:view,content');

Via Controllers

Laravel provides a helper method, called authorize that takes the name of the policy and the associated model as arguments, and either authorizes the action based on your authorisation logic or denies the action and throws an AuthorizationException which the Laravel Exception handler converts to a 403 HTTP response.

pubic function show($id)
{
    $content = Content::find($id);

    $this->authorize('view', $content);
        
    /* user can view content */
}

This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow