We strongly recommend that a Super-Admin be handled by setting a global Gate::before
or Gate::after
rule which checks for the desired role.
Then you can implement the best-practice of primarily using permission-based controls (@can and $user->can, etc) throughout your app, without always having to check for "is this a super-admin" everywhere. Best not to use role-checking (ie: hasRole
) (except here in Gate/Policy rules) when you have Super Admin features like this.
##Gate::before
If you want a "Super Admin" role to respond true
to all permissions, without needing to assign all those permissions to a role, you can use Laravel's Gate::before()
method. For example:
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
public function boot()
{
//...
// Implicitly grant "Super Admin" role all permissions
// This works in the app by using gate-related functions like auth()->user->can() and @can()
Gate::before(function ($user, $ability) {
return $user->hasRole('Super Admin') ? true : null;
});
}
}
NOTE: Gate::before
rules need to return null
rather than false
, else it will interfere with normal policy operation. See more.
Jeffrey Way explains the concept of a super-admin (and a model owner, and model policies) in the Laravel 6 Authorization Filters video and some related lessons in that chapter.
##Policy before()
If you aren't using Gate::before()
as described above, you could alternatively grant super-admin control by checking the role in individual Policy classes, using the before()
method.
Here is an example from the Laravel Documentation on Policy Filters
use App\Models\User; // could be any model
/**
* Perform pre-authorization checks on the model.
*/
public function before(User $user, string $ability): bool|null
{
if ($user->hasRole('Super Admin')) {
return true;
}
return null; // see the note above in Gate::before about why null must be returned here.
}
##Gate::after
Alternatively you might want to move the Super Admin check to the Gate::after
phase instead, particularly if your Super Admin shouldn't be allowed to do things your app doesn't want "anyone" to do, such as writing more than 1 review, or bypassing unsubscribe rules, etc.
The following code snippet is inspired from Freek's blog article where this topic is discussed further. You can also consult the Laravel Docs on gate interceptions
// somewhere in a service provider
Gate::after(function ($user, $ability) {
return $user->hasRole('Super Admin'); // note this returns boolean
});