Laravel policy send 403 for update and 201 for create

Issue

I have this policy :

class ProjectPagePolicy
{
    use HandlesAuthorization;

    public function viewAny(User $user)
    {
        return true;
    }
    public function view(User $user, ProjectPage $projectPage)
    {
        return true;
    }
    public function create(User $user)
    {
        return $user->isAdmin() || $user->isDeveloper();
    }
    public function update(User $user, ProjectPage $projectPage)
    {
        return $user->isAdmin() || $user->isDeveloper();
    }

    ..........
}

ProjectPageController :

class ProjectPageController extends Controller
{

public function __construct()
{
    $this->authorizeResource(ProjectPage::class, 'project-page');
}
public function index(Request $request)
{
    return response(
        [],
        HttpStatusCode::OK
    );
}
public function store(ProjectPageRequest $projectPageRequest)
{
    $inputs = $projectPageRequest->validated();

    $projectPage = ProjectPage::create($inputs);

    return response()->json([
        'data' => new ProjectPageResource($projectPage)
    ], HttpStatusCode::Created);
}
public function update(
    ProjectPageRequest $projectPageRequest,
    ProjectPage $projectPage
) {
    $inputs = $projectPageRequest->validated();

    $projectPage->fill($inputs)->save();

    return response(status: HttpStatusCode::NoContent);
}

In the routes file :

Route::middleware(['auth:sanctum'])->group(function () {
Route::post(
    '/refresh-token',
    fn () => app(RefreshTokenResponse::class)
);

Route::apiResources([
    'project-page'  => ProjectPageController::class,
]);

});

When I try to save a project page, I received 201 CREATED so all good in this case.

When I try to update it I have 403 forbidden.

Where the problem is ? Why is working on creation and not on updated ? Have an idea about that ?

Solution

TL;DR Remove the second argument ('project-page') from your authorizeResource call.


When using Route::resource(...), Laravel will convert a hyphenated route parameter to be snake-case (this will not have any affect on the URL itself, just how laravel accesses the parameter). This will mean that that when you call authorizeResource with project-page, it won’t match. This will in-turn cause the authorize method to fail.

You can view your routes via the CLI with the following:

php artisan route:list

which should show your route param for your project-page routes to be project_page e.g. project-page/{project_page}

Answered By – Rwd

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published