Политика Laravel 8 Всегда возвращает «Это действие является несанкционированным».

#php #laravel #backend #laravel-8 #policy

Вопрос:

Я пытаюсь создать политику для разрешений пользователя, поэтому я получаю разрешения пользователя из базы данных и проверяю, может ли он выполнить это действие или нет, но политика всегда возвращает 403:

Категорийконтроллер

У меня есть такой метод хранения, как этот

     public function store(Request $request)
{
    $user = auth('sanctum')->user();
    if (!$user) {
        return $this->ApiResponse(401,null,'Can not do this action without login, Login and tray again',);
    }

    $ability = "create-category";
    $this->authorize('can',[$user,Category::class,$ability]);

    $request->validate( [
        'name' => 'required|unique:categories',
        'parent_id' => 'nullable|integer|exists:categories,id',
        ]);

    try {
        $project = Category::create($request->all());
        return $this->ApiResponse(Response::HTTP_CREATED, "category created successfully",null, $project);
    }catch (Exception $e) {
        return $this->ApiResponse(500, 'category can't be created try later');
    }
}
 

Политика категорий

У меня есть такой метод, как этот

 public function can (User $user,Category $category,string $ability)
{
    $role = Role::with('permissions')->find($user->role_id);
    $permissions = $role->permissions;

    for ($i=0; $i<count($permissions); $i  ) {
        $userPermissions[$i] = $permissions[$i]['name'];
    }
    if (in_array($ability, $userPermissions)) {
        return true;
    }
    return false;
}
 

AuthServiceProvider

  protected $policies = [
    Category::class => CategoryPolicy::class,

];
 

так в чем же проблема??

Ответ №1:

Я думаю, что вы просто перепутали некоторые параметры

Вместо

 $this->authorize('can',[$user,Category::class,$ability]);
 

Вы, наверное, хотите

 $this->authorize('create-category', Category::class);
 

или, если вы не хотите указывать sanctum в качестве охранника, Auth::shouldUse() например, вы можете использовать следующее:

 $this->authorizeForUser(auth('sanctum')->user(), 'create-category', Category::class);
 

и в своей политике вы можете упростить аргументы, чтобы:

 public function createCategory(User $user, Category $category)
 

Если вам нужно выполнить какие-либо проверки по $ability значению, вы можете использовать фильтры политики:

 
class CategoryPolicy
{
    /**
     * Perform pre-authorization checks.
     *
     * @param  AppModelsUser  $user
     * @param  string  $ability
     * @return void|bool
     */
    public function before(User $user, $ability)
    {
        if ($user->permissions->where('name', $ability)->isEmpty()) {
            return false;
        }
    }

    // ...
 

Комментарии:

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

2. первым аргументом метода authorize() должно быть имя метода политики, после чего мы можем передать массив в качестве второго аргумента.

3. Мне нужно вызвать подобный метод public function createCategory(User $user, Category $category, string $ability) из CategoryController и передать action

4. Любая подобная логика может быть реализована с помощью фильтров политики. Я отредактирую ответ с помощью примера.