yougotnet's avatar

Policies not blocking edits

If I put in the browser /post/3/edit; nothing in the PostPolicy will catch this. If I just put /post/3, then the view function will catch it.

How can I protect the /edit?

0 likes
4 replies
LaryAI's avatar
Level 58

Certainly! Here’s a solution to your Laracasts forum question, "Policies not blocking edits":


When you visit /post/3/edit, the typical mechanism in Laravel is for the controller method (usually edit()) to handle this route. However, authorization policies do not apply automatically to every controller method — you must explicitly check policy permissions when opening "edit" pages.

For view pages (/post/3), you might be using route model binding in combination with implicit policy checks (using, for example, resource controllers with authorizeResource() or authorize() middleware). For edit pages, you need to ensure authorization is also checked in your controller.

How to Protect /edit:

1. Manually Check Policy in the edit() Method

In your controller's edit method, add:

public function edit(Post $post)
{
    $this->authorize('update', $post);

    // Now return the edit view
    return view('posts.edit', compact('post'));
}

This uses Laravel's built-in authorization to check the update function of your PostPolicy.

2. Use Controller Authorization Helpers

If you're using a resource controller, you can add authorization globally by adding this line to your controller's constructor:

public function __construct()
{
    $this->authorizeResource(Post::class, 'post');
}

This will automatically apply the relevant policy methods (view, update, delete, etc.) to the resource controller's methods, including edit.

3. Use Middleware (Optional)

You can also use a middleware to check policy:

Route::get('/post/{post}/edit', [PostController::class, 'edit'])
    ->middleware('can:update,post');

This route middleware will ensure only authorized users can access the edit page.


Summary

Authorization policies are not automatically applied to edit routes. You need to explicitly authorize the user before showing the edit page, either inside your controller or via route middleware.


Let me know if you need a tailored code example for your specific use case!

yougotnet's avatar

$this-authorize() function does not exists.

jlrdw's avatar

You can't go by the URL, you ensure the auth id is used and they are authorized to perform the edit. For example edit their own data but not someone else's.

There are also numerous videos here on authentication and authorization.

Basically

  • Authentication = logged in
  • Authorization = what they can or cannot do.

A query scope can be used to (for example) to show only the authenticated user their data only. Never get this from the URL but from Auth::user()->id. I use the facade.

The exception, and just example, a manager is editing employee data. They click edit in the table next to Joe Smith to bring up the edit page. So in case of a known good manager when editing (who is authorized), the URL id is used.

Whereas if Joe Smith is editing his data, do not allow the data from the URL.

1 like

Please or to participate in this conversation.