Photo of Christoph Rumpel

New ACL features in Laravel 5.1.11

Since the Laravel 5.1.11 release it is providing some great new authorization features. Let's dive right in.

So we all already know about the Authentication features in Laravel. They are nice, but in many applications just a start in handling your users. We always need some kind of permissions too. Who is allowed to update this comment? Or are there some users who should be allowed to do all kind of actions? These are the questions we are going to answer here.

Setting abilities

So there is this new Laravel class Illuminate\Auth\Access\Gate handling setting and checking, so called, abilities. The Laravel AuthServiceProvider is the recommended place to define such an ability. In our case we would like to protect our comments.

// Inside AuthServiceProvider
// ...

public function boot(GateContract $gate)
{
    parent::registerPolicies($gate);

    $gate->define('update-comment', function ($user, $comment) {
        return $user->id === $comment->user_id;
    });
}

Inside the boot method we are defining the update-comment ability. We only want users to update a comment if it belongs to them. This is what we are checking here.

Note: It is also possible to set a class and method like 'Class@method' as the second parameter instead of the closure.

Checking abilities through the Gate facade

Now that we set our permission, we'd like to check it before updating a comment.

// inside the CommentController
// ...

public function update($id)
{
    $comment = comment::findOrFail($id);
    
    if (Gate::denies('update-comment', $comment)) {
        abort(403);
    }

    // Update Comment...
}
Note: We do not need to pass the user object to the denies method. The Gate facade will take the current authenticated user automatically.

It is possible to use the opposite Gate method allows too.

 
if (Gate::allows('update-comment', $comment)) {
    // Update Comment...
}

Checking abilities through the model instance

And of course there is another way to check our udpate-comment permission. This time we are using the user instance and the new can or cannot methods.

// Inside the CommentController
// ...

if ($request->user()->cannot('update-comment', $comment)) {
    abort(403);
}

Both accomplish the same task, so it is up to you to decide which way you prefer.

There is always a super admin

I guess in every application there is a super admin with super powers. Of course he or she shouldn't be hindered by our Gate. For this case Laravel provides an additional before method. Just place it inside the AuthServiceProvider again. Now we just need to provide the information if this user should have all rights. In this case it is a method, but it also could be a database field or something else. This is totally up to you.

$gate->before(function ($user, $ability) {
    if ($user->isSuperAdmin()) {
        return true;
    }
});

Use it in Blade

Still not enough? Great, because here is more. You can make use of this features in Blade too. This comes handy when we want display something depending on the user's permissions. In our case we want to show an edit link for comments which belong to me. Here we go!

// Inside a blade template file
// ...

@can('update-comment', $comment)
    {% raw %}<a href="/comment/{{ $comment->id }}/edit">Edit Comment</a>{% endraw %} 
@endcan

Conclusion

Laravel 5.1.11 was a small release, but it is still providing some great new ACL features to the framework. Read more about it here and start toying around.

Let's stay in touch

Sign up for my newsletter and I will let you know about more content and new projects of mine once a month.