Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jmacdiarmid's avatar

Using Policies with Spatie/Laravel-permissions

I want to add roles and permissions to a laravel forum app based on the tutorial here: Creating a Laravel Forum Using Laravel 8

However, this tutorial that demonstrates how to add roles and permissions manually without a package using a single guard, User Policy, Middleware and a LoginResponse class to handle redirection based on the role of the auth user.

I'm attempting to do something similar using the Spatie/Laravel-Permissions package. When doing this, I'm finding that the HasAnyRole method and the Can method are not recognized in certain areas of the code as shown below. Another reason I'm asking is that doing this with a Policy seems redundant.

Do I need policies (guards and gates?)? Is there a more efficient, cleaner way of adding roles and permissions using spatie/laravel-permissions?

User Model

use HasRoles; 

const DEFAULT = 1; 
const MODERATOR = 2;
const ADMIN = 3;

/** A type column was added to the User table migration **/
public function type(): int
{
    return (int) $this->type;
} 

public function isModerator(): bool
{
    return $this->type() === self::MODERATOR;
}

public function isAdmin(): bool
{
    return $this->type() === self::ADMIN;
}

UserPolicy class

const ADMIN = 'admin';

public function admin(User $user): bool
{
	return $user->isAdmin();
}

AuthServiceProvider Class

UserPolicy reference is added here

protected $policies = [
	User::class => UserPolicy::class;
];

CheckIfAdmin Middleware Class

Note: One issue I'm having here is that the "can" method is not recognized in the Auth

class CheckIfAdmin
{
		public function handle(Request $request, Closure $next, $guard = null) {

			//  In this condition, the hasAnyRole() method is not found in Auth::guard($guard)->user() 
			 if(Auth::guard($guard) && Auth::guard($guard)->user()->hasAnyRole(['super-admin', 'admin']) ){
					//
        	}

			// Also, in this condition, the can() method is not found in Auth::guard($guard)->user() 
			if(Auth::guard($guard)->user()->can(UserPolicy::ADMIN, User::class) {
 				return $next($request);
		   }
		   throw new HttpException(403, 'Forbidden');
		}
}

LoginResponse Class

No errors found in this code according to PHPStorm.

namespace App\Http\Responses;

use Laravel\Fortify\Contracts\LoginResponse as ContractsLoginResponse;

class LoginResponse implements ContractsLoginResponse
{
    public function toResponse($request)
    {
        if (auth()->user() && auth()->user()->hasRole('administrator')) {
            return redirect()->route('admin.index');
        }
        return redirect()->intended(config('fortify.home'));
    }
}
0 likes
4 replies
jmacdiarmid's avatar

@jlrdw Thank you for your reply. I've been reading and following the documentation, however, I'm not clear on if I need to add the spatie/laravel-permissions statements, conditions and so forth to a policy or if I need to set up a Response class to handle the redirection on login. I added the middleware which came with the spatie package to the routemiddleware array in app/http/kernel.php.

'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
 'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
 'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,

So, unless I'm missing something outside of that, I'm guessing I can add the "can", "hasRole" or "hasAnyRole" as needed to check on the permission and role specifics regarding what they can do or can not do. Does that sound right?

I also found this thread on SO regarding the use of a custom middleware to handle redirection on login. Laravel redirect based on role - spatie/laravel-permission

After reading it a few times, I think it's saying that I should be able to use the custom middleware for the redirection instead of the middleware that comes with the spatie package though I haven't tested it yet.

Snapey's avatar

permissions tell you if someone has role or permission to do the action

policies tell you if someone has role or permission to do the action with a specific thing

So whether you need policies is determined by the type of application. For instance, In an HR application I might be a 'manager' and have permission to approve holidays but only for members of my own team

2 likes
jmacdiarmid's avatar

@Snapey Thanks for that info. That makes sense. I was confused since I was attempting to add the spatie role and permission checks in a userpolicy/loginresponse to apply it to the tutorial I've been following when it doesn't appear I need to go that far.

Please or to participate in this conversation.