I need to authorize users on a forum.
So in blade, I have @can('editPost', $post)
before showing the form to reply to a topic. My PostPolicy
class has a editPost
method that validates to true if it's the users own post.
However, the issue appears when I want to do a simple check, like deletePost()
. This checks to see if Auth::user()->isAdmin
public function deletePost(User $user) {
return Auth::user()->isAdmin;
// return $user->isAdmin
}
However, this won't even get called, since I'm not passing an instance of Post
My real world application is much more complicated, but I'm using isAdmin
as a simple example.
I guess defining $gate->define('deletePost', 'App\Policies\PostPolicy@deletePost');
in AuthServiceProvider
could work, but would end up separating my definitions and methods, and ultimately for a large app clutter the AuthServiceProvider
An authorization policy either grants or excludes permission to a user or user group, acting in one of more roles, to perform an operation on an type of object, for a resource which is scoped by its resource type. The elements of an authorization policy are described below: User. Who initiates the operation.
In addition to providing built-in authentication services, Laravel also provides a simple way to authorize user actions against a given resource. For example, even though a user is authenticated, they may not be authorized to update or delete certain Eloquent models or database records managed by your application.
Policies in Laravel: Laravel Gates and policies are like routes and controllers, respectively. Gates allows users to define an authorization using a simple closure-based approach. If you want an action unrelated to any specific model, gates are perfect to use.
When you register a policy it is the classname that is used to route checks to the class, so in order to get routed to the policy you can just pass the class name of the type you registered it with.
Try using @can('delete', Post::class) and see if that gets you there
refer to Illuminate\Auth\Access\Gate::firstArgumentCorrespondsToPolicy
EDIT After a little more diggin I found this https://github.com/laravel/framework/commit/70f75255808ffc96275e6f2f356616dd2e163434#diff-961368895033e553787b301c3be0e17a
so it looks like if you on version 5.1.23 then you will be able to pass a string otherwise your will need to just pass new Post
In controllers
$this->authorize('<ability>', <Class-With-Rule::class> | <Full-Path-To-Class>);
In Blade view
@can('<ability>', <Class-With-Rule>::class> | <Full-Path-To-Class>)
In Eloquent model
$user->can('<ability>', <Class-With-Rule>::class> | <Full-Path-To-Class>);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With