Политика Laravel всегда неверна

Я пытаюсь разрешить пользователю просматривать свой профиль в Laravel 5.4.

UserPolicy.php

public function view(User $authUser, $user) { return true; } 

зарегистрированная политика в AuthServiceProvider.php

 protected $policies = [ App\Task::class => App\Policies\TaskPolicy::class, App\User::class => App\Policies\UserPolicy::class ]; 

Маршруты

 Route::group(['middleware' => 'auth'], function() { Route::resource('user', 'UserController'); } ); 

Шаблон клинка

 @can ( 'view', $user ) // yes @else // no @endcan 

UserController.php

 public function profile() { return $this->show(Auth::user()->id); } public function show($id) { $user = User::find($id); return view('user.show', array( 'user'=>$user,'data'=>$this->data ) ); } 

Возврат всегда «ложный». То же самое для вызова политики формирует контроллер. Где я ошибаюсь?

Ответ на мой собственный вопрос кажется странным, но я ненавижу его, когда сталкиваюсь с вопросами без последующих действий.

Поэтому после двойной проверки выяснилось, что если я удалю authorizeResource из конструктора

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

и проверить авторизацию в функции контроллера

  $this->authorize('view',$user); 

все работает. Я, должно быть, пропустил эту часть, когда я добавил $user в качестве параметра в функции политики. Таким образом, пользователь, который будет просматриваться, никогда не передается в методе authorizeResource .

Спасибо всем, что нашли время, чтобы помочь мне.

Просто другой подход к пользователям, просматривающим свой профиль.

Во-первых, я создам маршрут для этого

 Route::group(['middleware' => 'auth'], function() { Route::get('profile', 'UserController@profile'); }); 

Тогда в функции profile я делаю

 public function profile() { $user = Auth::user(); return view('profile', compact('user')); } 

Таким образом, пользователь автоматически просматривает только свой профиль.

Теперь, если вы хотите разрешить некоторым пользователям просматривать другие профили, вы можете использовать политику. Зачем? Потому что я думаю, что пользователь должен ВСЕГДА просматривать свой профиль. Но не все пользователи должны просматривать другие профили пользователей.

Решение:

Измените второй параметр из @can( 'view', $user ) на @can( 'view', $subject ) и он будет работать.

Зачем:

Потому что вы делаете это неправильно.

 public function view(User $user, $subject){ return true; } 

Просто внимательно посмотрите на метод просмотра политики, первый параметр – authenticated user или current user а второй параметр – $subject , так как политики организуют логику авторизации вокруг моделей.

Политики – это классы, которые организуют логику авторизации вокруг определенной модели или ресурса. Например, если ваше приложение является блогом, у вас может быть модель Post и соответствующая PostPolicy для авторизации действий пользователя, таких как создание или обновление сообщений.

если вы хотите пойти дальше глубоко внутри него.

https://github.com/laravel/framework/blob/5.3/src/Illuminate/Auth/Access/Gate.php#L353

 /** * Resolve the callback for a policy check. * * @param \Illuminate\Contracts\Auth\Authenticatable $user * @param string $ability * @param array $arguments * @return callable */ protected function resolvePolicyCallback($user, $ability, array $arguments) { return function () use ($user, $ability, $arguments) { $instance = $this->getPolicyFor($arguments[0]); // If we receive a non-null result from the before method, we will return it // as the final result. This will allow developers to override the checks // in the policy to return a result for all rules defined in the class. if (method_exists($instance, 'before')) { if (! is_null($result = $instance->before($user, $ability, ...$arguments))) { return $result; } } if (strpos($ability, '-') !== false) { $ability = Str::camel($ability); } // If the first argument is a string, that means they are passing a class name // to the policy. We will remove the first argument from this argument list // because the policy already knows what type of models it can authorize. if (isset($arguments[0]) && is_string($arguments[0])) { array_shift($arguments); } if (! is_callable([$instance, $ability])) { return false; } return $instance->{$ability}($user, ...$arguments); }; } 

См. Последнюю строку, в которой он вызывает метод с аргументом $ user и $ (в нашем случае Model).

Документы Laravel для авторизации / политики