Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

JoshWegener's avatar

Calling authorize policy from a Form Request?

Hello! I have a quick question. I want all of my auth logic to be in a policy, but I use a form request class when something is posted for updating/creating so I want to be able to call $this->authorize('store', $post); inside the request NOT the controller.

IE:

// controller
public function store(StorePostRequest $request) {
}
// request
public function authorize()
{
    $post = Post::findOrFail($this->route('post'));
    return $this->authorize('store', $post);
}
0 likes
19 replies
JoshWegener's avatar

Of course they can, but why have 1/2 your auth logic in the request, and the other 1/2 in a police? I would just prefer to have it all in one location for that controller.

d3xt3r's avatar

1/2 your auth logic in the request, and the other 1/2 in a police

No it doesn't. All the authorisation logic is up to you, which in ideal cases should be delegated to policies. Its just a place holder for defining which policies should be checked, the same that you do in controller.

You can very well do it by yourself without defining any policy and checking it in the request itself.

JoshWegener's avatar

Maybe I'm not being clear....

If I do this way for example:

// controller
public function store(StorePostRequest $request) {
    $this->authorize('store', $post);
}

Then you will be validating the data before checking if they even have access... So lets say they POST a store, then they might see "foo bar is required", when they are not even authorized to post in the first place. Meaning, you need to authorize BEFORE you validate. So I assumed the best way would to be just call the police from the request....

2 likes
d3xt3r's avatar

So I assumed the best way would to be just call the police from the request....

Yes, if already using a form request, ideal place for authorisation is the form request itself. I still don't understand what is bothering you, as this is the feature that is supported.

The sequence in which form request is validated already takes care of your concern

/**
     * Validate the class instance.
     *
     * @return void
     */
    public function validate()
    {
        $instance = $this->getValidatorInstance();

        if (! $this->passesAuthorization()) {
            $this->failedAuthorization();
        } elseif (! $instance->passes()) {
            $this->failedValidation($instance);
        }
    }
JoshWegener's avatar

Correct, but what I would like to do is place the auth in the police NOT the request... The request should handle the request, the police should handle all the auth...

So a year from now, if I want to know how auth is on the Post, I can look in the PostPolice, and not have to dig around in the request as well.

d3xt3r's avatar

So a year from now, if I want to know how auth is on the Post, I can look in the PostPolice, and not have to dig around in the request as well.

You are confused and making me confused as well.

how auth is on the Post.

The actual logic is still in the policy

and not have to dig around in the request as well.

You don't dig to find how you have defined the policy BUT where it has been used.

Do you have a specific example in mind, which we could work out to make thing clear for you.

JoshWegener's avatar

Maybe I'm special... I'm just asking how can I call the policy from a request?

d3xt3r's avatar
d3xt3r
Best Answer
Level 29

At-least read the whole documentation ? Abilities, policies, these are big words, don't let then confuse you, when you define ACL on object itself as to who can do what, its called policy. When you define it on user, its called ability.

Example: Ability

 $gate->define('update-post', function ($user, $post) {
            return $user->id === $post->user_id;
        });

if (Auth::user()->can('update-post', $post)) {
    // Update Post...
}

Policy

<?php

namespace App\Policies;

use App\User;
use App\Post;

class PostPolicy
{
    /**
     * Determine if the given post can be updated by the user.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}

if (Auth::user()->can('update', $post)) {
    //
}

Where do you see the difference ?

2 likes
JoshWegener's avatar

I didn't understand that... I think I get it now! Both are registered to the "gate"...

$user->can('update', $post);

is same as

Gate::allows('update', $post)

and same as

// in a controller
$this->authorize('update', $post);

And it pulls this from the Police if defined...

1 like
JoshWegener's avatar

Quick follow up question, how would you store that in the database in a permissions table?

The idea is, when I call the police, the police will look for a "slug" in the permissions table to see if they match... what do you suggest for this naming convention? mode-method?

class PostPolicy
{
    /**
     * Determine if the given post can be updated by the user.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */
    public function update(User $user, Post $post)
    {
        return $user->hasPermission('post-update');
    }
}

Something like that?

Then the table:

permissions
---------------
id (1)
name ('Update a Post')
slug ('update-post')
d3xt3r's avatar
 public function update(User $user, Post $post)
    {
        return $user->hasPermission('post-update');
    }

This is of RBAC sorts , no where it says whether the user can update the post in question, but yes model-action sounds good.

JoshWegener's avatar

I guess this would be more accurate

class PostPolicy {
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id || $user->hasPermission('post-update');
    }
}
class PostController {
    public function store(StorePostRequest $request) {
        $post = $request->user()->posts()->create([
            'title ' => $request->title,
            'body' => $request->body,
        ]);
        return redirect('post.show', compact('post'));
    }
}
class StorePostRequest {
    public function rules()
    {
        return [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ];
    }

    public function authorize()
    {
        Auth::user()->can('update', $post)
    }
}
3 likes
d3xt3r's avatar

seems right , a user can update his own post or if he is moderator with update post permission.

torkil's avatar

In the Request class, you can also do

$this->user();

to access the currently authenticated user, instead of using the Auth facade as mentioned above.

1 like

Please or to participate in this conversation.