Skip to content
Advertisement

Can’t get Laravel middleware “can:something” to work with my policy

I want to make sure that the current user is able to edit the users credentials so I made the following UserPolicy:

class UserPolicy
{
    use HandlesAuthorization;

    public function update(User $user, User $model)
    {
        return true;
        //return $user->is($model);
    }
}

I even registered the policiy inside AppServiceProvider:

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

Now I try to add the following middleware to the update-route in web.php: “->middleware(‘can:update,user’);” like this:

Route::patch('/profiles/{user}',function (){
    dd('It works');
})->middleware('can:update,user');

But I keep getting the following error:

Error Class ‘2’ not found

Where 2 is the user-id who we try to patch. If I was logged in with user-id 1 that will be the class not found. I don’t understand why. I followed the documentation on Laravel website (https://laravel.com/docs/8.x/authorization#via-middleware).

I have also tried to set {user} to {user:id} -> Same result
I have tried adding the id on “can” like this: can:update,user:id -> Gives 403 not authorized

The edit.blade.php has the following:

    <form action="/profiles/{{ auth()->user()->id }}" method="POST">
        @csrf
        @method('PATCH')
        ...INPUTS...
    </form>

I have of course tried running: “php artisan optimize” with no effect

What am I missing here? What’s wrong?

EDIT:

I now tried the same thing with a Gate instead. I put the following inside AppServiceProvider.php:

public function boot()
{
    Gate::define('edit-user', function(User $currentUser, User $user){
        return true;
        //return $currentUser->id === $user->id;
    });
}

And the following middleware inside web.php:

Route::patch('/profiles/{user}',function (){
    dd('It works');
})->middleware('can:edit-user,user');

And it gives me the exact same error: Class 2 not found

I even tried to pass the full models path like this:

Route::patch('/profiles/{user}',function (){
    dd('It works');
})->middleware('can:edit-user,AppModelsUser');

And it gives me the following error:

Argument 2 passed to AppProvidersAppServiceProvider::AppProviders{closure}() must be an instance of AppModelsUser, string given, called in /var/www/vhosts/domain.com/httpdocs/vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php on line 474

Advertisement

Answer

I would think it is due to not using model binding, you are passing the id where it expects an user model. Check if this version works.

Route::patch('/profiles/{user}',function (User $user) {
    dd('It works');
})->middleware('can:edit-user,user');
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement