Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Policy not working #16184

Closed
trunglh88 opened this issue Oct 30, 2016 · 9 comments
Closed

Policy not working #16184

trunglh88 opened this issue Oct 30, 2016 · 9 comments

Comments

@trunglh88
Copy link

trunglh88 commented Oct 30, 2016

  • Laravel Version: 5.3.21
  • PHP Version:
  • Database Driver & Version:

Hi all,
i'm using Policy to authorization but it's not working on all route.

Description

1.Create default controller using

php artisan make:controller PostController --resource

2.Create policy

php artisan make:policy PostPolicy --model=Post

3.In PostPolicy return true for each action (view, create, update, delete)

public function view(User $user, Post $post) { return $user->id === 1; }

4.Register policy in the AuthServiceProvider

protected $policies = [ 'App\Model' => 'App\Policies\ModelPolicy', Post::class => PostPolicy::class, ];

5.In web.php add routes

Route::resource('post', 'PostController');

6.in PostController add authorizeResource method

public function __construct() { $this->authorizeResource(Post::class); }

7.Access to URL from browser.

METHOD
[GET] http://laravel.local:8000/post (post.index) ==> worked
[DELETE] http://laravel.local:8000/post/1 (post.destroy) ==> worked
[GET] http://laravel.local:8000/post/create (post.create) ==> worked
[POST] http://laravel.local:8000/post/create (post.store) ==> worked
[GET] http://laravel.local:8000/1/edit (post.edit) ==> Error : This action is unauthorized.
[GET] http://laravel.local:8000/1 (post.show) ==> Error : This action is unauthorized.

8.in post_index.blade

@can('view', $post) <a href="{{ route('post.show', ['post' => $post])}}">Show</a> @endcan

@can('update', $post) <a href="{{ route('post.edit', ['post' => $post])}}">Edit</a> @endcan

Result : Show, Edit link is display correct. (in view check policy is correct ??)

2 routes : edit and show is not working.

@prateekkathal
Copy link

prateekkathal commented Oct 30, 2016

Hello @vocal

Shouldn't the 2 routes that are not working be like...

[GET] http://laravel.local:8000/post/1/edit
[GET] http://laravel.local:8000/post/1

post is missing from those 2 routes...

Also, I am unsure as to how you are getting This action is unauthorized instead of 404 Not Found. If you comment out the line having $this->authorizeResource(...) and try dd("Post") inside edit() or show() function, does it work?

Lastly, I am unsure as to why you are really using Policies if you are not doing something like

return $user->id == $policy->user_id;

//Instead of return $user->id === 1; Or is it just for testing purposes?

@trunglh88
Copy link
Author

trunglh88 commented Oct 30, 2016

Hi @prateekkathal

This action is unauthorized is exception throw by Illuminate\Auth\Access\AuthorizationException (403 Error)

if i comment out $this->authorizeResource(...) then inside edit() show() function working fine.

i'm using return $user->id === 1; (user logged id = 1) or return true; for testing but still error at 2 routes edit() and show()

if i using

Route::group(['prefix' => 'post', 'middleware' => 'auth'], function () {
Route::post('/', 'PostController@store')->name('post.store');
Route::get('/', 'PostController@index')->name('post.index');
Route::get('/create', 'PostController@create')->name('post.create')
->middleware('can:create,App\Post');
Route::delete('/{post}', 'PostController@destroy')->name('post.destroy')
->middleware('can:delete,post');
Route::put('/{post}', 'PostController@update')->name('post.update')
->middleware('can:update,post');
Route::get('/{post}', 'PostController@show')->name('post.show')
->middleware('can:view,post');
Route::get('/{post}/edit', 'PostController@edit')->name('post.edit');
});

instead of

Route::resource('post', 'PostController');

then post.edit route working fine but post.show still 403 error

@trunglh88
Copy link
Author

I have found the problem.
When i pass parameter in to edit(Post $post) and show(Post $post) then it working.

@straube
Copy link

straube commented Jun 22, 2017

I had the same issue and I can confirm the error goes away after changing the show method signature from:

show($id)

to:

show(Post $post)

I just don't understand why that's happening. It seems like Laravel docs don't even mention the authorizeResource method.

@mjsarfatti
Copy link

Same problem here, more than two years later it appears.
Looks like a note/warning could be added to the docs?

@raksa
Copy link

raksa commented Jan 10, 2019

Laravel 5.7
face same problem:
with Controller call authorizeResource

public function __construct()
{
$this->authorizeResource(Model::class);
}

i see root cause, getting policy via Illuminate\Auth\Access\Gate::getPolicyFor return null for argument is Model::id's value
authorize middleware of show, edit, update and destroy are generated to "can:{ability},{route}" so it will let Illuminate\Auth\Middleware\Authorize::getModel return string id, not Model

@joveice
Copy link

joveice commented Jan 11, 2019

Same here

class QueryPolicy

    /**
     * Determine whether the user can delete the query.
     *
     * @param  \App\User  $user
     * @param  \App\Query  $query
     * @return mixed
     */
    public function delete(User $user, Query $query)
    {
        return $user->id === $query->user_id;
    }

class QueryController

    public function __construct()
    {
        $this->authorizeResource(Query::class);
    }

class AuthServiceProvider

    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
        Query::class => QueryPolicy::class,
    ];

EDIT: I had a type in my route
from this

Route::resource('queires', 'QueryController');

to this

Route::resource('queries', 'QueryController');

@akseen
Copy link

akseen commented Sep 10, 2019

I have found the problem.
When i pass parameter in to edit(Post $post) and show(Post $post) then it working.

Thanks a ton dude! I was going mad trying to strictly follow proper laravel conventions.

@Joren-Thijs
Copy link

I have found the problem.
When i pass parameter in to edit(Post $post) and show(Post $post) then it working.

I had the same issue on my user controller.

On all my controllers i also made the mistake of using a plural with the authorizeResource command since my routnames are plurals like 'domain/leases'

public function __construct()
{
    $this->authorizeResource(Lease::class, 'leases');
}

changing it to

public function __construct()
{
    $this->authorizeResource(Lease::class, 'lease');
}

// or
public function __construct()
{
    $this->authorizeResource(Lease::class);
}

Fixed the issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants