Search code examples
apirequestauthorizationlaravel-5.6policy

cant pass the request to policy so i can validate some issues


i authorize store like this

    public function store( Request $request)
{
    $this->authorizeApi('store',JobPost::class, $request);
    return $this->jobPostRepository->store($request);
}

and in policies my store method looks like this

    public function store(Request $request)
{
    $user=auth()->user();
    return ($user->company_id == $request->company_id)
        &&($request->expiration_date->isAfter($request->publish_date))
        &&($request->publish_date->isAfter(now()))
        ;
}

when i run this i get

"Argument 1 passed to App\Policies\JobPostPolicy::store() must be an instance of Illuminate\Http\Request, instance of App\Models\User given, called in C:\xampp\htdocs\balatar1\vendor\laravel\framework\src\Illuminate\Auth\Access\Gate.php on line 481"

when i dd the request in the controller its ok but when i dd it on the policy it returs a null User object!!! why is that?


Solution

  • You did some mistakes and miss something.

    As I know you have some companies and each Company has some JobPosts.

    First, you should not pass your company id in the body of job post request instead, your store route should be something like https://example.com/company/{company_id}/job-post then you are able to catch company model via the Laravel model binding!

    so your routes should be defined as:

    Route::group(['prefix' => 'company', 'as' => 'company.'], function () {
        Route::group(['prefix' => '{company}'], function () {
            Route::resource('job-post', 'JobPostController', ['parameters' => ['job-post' => 'jobPost']);
        });
        Route::resource('', 'ComapnyController', ['parameters' => ['' => 'company']);
    }
    

    And your controller looks like (I'll have explained the JobPostRequest by the second part of the answer):

    class JobPostController extends Controller
    {
        public function store(JobPostRequest $request, Company $company)
        {
            $this->authorizeApi('store', [JobPost::class, $company]);
    
            // the rest...
        }
    }
    

    Second, What you need is a Request class to do validations for you.

    based on the documentation firstly you have to create a Request class, then it needs to run php artisan make:request JobPostRequest

    Then your job post request should be something like:

    class BaseRequest extends FormRequest
    {
        /**
         * Determine if the user is authorized to make this request.
         *
         * @return bool
         */
        public function authorize()
        {
            return true;
        }
    
        /**
         * Get the validation rules that apply to the request.
         *
         * @return array
         */
        public function rules()
        {
            return [
                'title' => 'required|max:255',
                'body' => 'required|max:65535',
            ];
        }
    }
    

    You could also do what you've done in your policy, in the above class authorize method but is not recommended.

    Third, In your policy (JobPostPloicy) you'll have to check if currently logged in user is able to post a job for the given $company or not.

    P.S. Please copy and past your classes completely with all dependencies and spend a little more time to butify your post. If this is hard to write your question, this is hard to read, understand, and answer it correctly.