I have the following middleware in my PostController
.
public function __construct()
{
$this->middleware('auth')->except(['index', 'show']);
}
I understand any authenticated user can still edit a post by visiting localhost/posts/{post}/edit
so I've protected that by the following code.
public function edit(Post $post)
{
if(auth()->user()->id === $post->user_id){
$categories = Category::all();
return view('edit-post', compact(['post', 'categories']));
} else{
abort(403, 'Unauthorized.');
}
}
Now, I'm wondering is it necessary to protect the destroy method? Is it possible for an authenticated user to delete a post they didn't create in this case? If they can could I kindly know how they can?
My destroy method
public function destroy(Post $post)
{
Storage::disk('public')->delete($post->imagePath);
$post->delete();
return redirect(route('posts.index'))->with('flash', 'Post Deleted Successfully');
}
CodePudding user response:
First, you should be read about Laravel policy, which will make your code more clear.
For destroy method,
I will give you an example, you can try it BTW
post_table
id | user_id | title |
---|---|---|
1 | 40 | Post1 |
2 | 50 | Post2 |
If the user id: 40
tries to delete the post witch id is id: 1
there is no problem,
BUT let's say the user knows about the web app and just changes the id
in the URL localhost/posts/2/delete
, He/She will delete any post without policy.
CodePudding user response:
one easy way to protect all your methods that need authentification is to use relations.
You are sending a post id in the URL by use model injection to preload $post
from DB. Avoid that and use the id of the post yourself
public function destroy($postId)
{
$post = auth()->user()->posts()->findOrFail($postId);
Storage::disk('public')->delete($post->imagePath);
$post->delete();
return redirect(route('posts.index'))->with('flash', 'Post Deleted Successfully');
}
The route will return a 404 if the post id is not one of the user owned posts.
Same for the edit
public function edit($postId)
{
$post = auth()->user()->posts()->findOrFail($postId);
$categories = Category::all();
return view('edit-post', compact(['post', 'categories']));
}
As for the change in response code 404 instead of a 403, it is on purpose, since the user is authenticated and you dont want any user to know if another post with random ID that is not his exists or not hence 404. like if he put a non existing post id to delete or edit.