0

In my Laravel project I want to authorize user via a Request like this:

<?php

namespace Domain\Contents\Http\Requests\Blog;

use Domain\Contents\Models\Blog\Post;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;

class ReadPostRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        if (request('id') === null) {
            abort(403);
        }

        $post = Post::whereId(request('id'))->first();

        return Gate::allows('view-post', $this->user(), $post);
    }

    // ...
}

But I think here this part of my code is little bit messy:

if (request('id') === null) {
    abort(403);
}

$post = Post::whereId(request('id'))->first();

Is there any simpler solution for accessing current Post model in the Request class?

netdjw
  • 5,419
  • 21
  • 88
  • 162
  • Your code seems confused. You return 403 if it isn't null, so why do the `whereId` line afterward if you know the ID is null? – miken32 Nov 22 '21 at 19:11
  • If you don't have authorization to access posts, then you don't have access for find out what post ID exists and what not exists. So if you try to access a not existing post 404 is not a good answer, because it means something not exists. But the correct answer is "none of your business". But if you want to get an existing post, then I have a policy what'll decide the authorization. – netdjw Nov 22 '21 at 19:18
  • But you **always** return 403, unless ID is null. So by the time you get to your `whereId` line, you already know ID is null, it will never get a post object. – miken32 Nov 22 '21 at 19:22
  • ohhh you're right :) I fixed it already in my code, but not in this example. I fixed it right now. – netdjw Nov 22 '21 at 19:25

2 Answers2

1

The documentation for FormRequests suggests that the authorize() method supports type hinting.

If you are using route model binding you could therefore just type hint the post:

public function authorize(Post $post)
{
    return Gate::allows('view-post', $this->user(), $post);
}
Rory
  • 2,175
  • 1
  • 27
  • 37
1

Alternative solution is that you can directly access your Models that are used with Model Binding.

return Gate::allows('view-post', $this->user(), $this->post);

For ease of use you can typehint it in the comments.

/**
 * @property \App\Models\Post $post
 */
mrhn
  • 17,961
  • 4
  • 27
  • 46