【问题标题】:Laravel 8 Policy Always returns "This action is unauthorized."Laravel 8 Policy 总是返回“此操作未经授权”。
【发布时间】:2021-08-10 22:59:23
【问题描述】:

我正在尝试为用户权限创建策略,因此我从数据库中检索用户权限并检查他是否能够执行此操作,但该策略始终返回 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,

];

那么问题是什么??

【问题讨论】:

    标签: php laravel backend laravel-8 policy


    【解决方案1】:

    我认为你只是混淆了一些参数

    而不是

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

    你可能想要

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

    或者,如果您不想通过例如Auth::shouldUse()sanctum 指定为守卫,则可以使用以下内容:

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

    在您的政策中,您可以将参数简化为:

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

    如果您需要对$ability 值进行任何检查,您可以使用policy filters

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

    【讨论】:

    • authorize() 方法的第一个参数必须是策略方法的名称,然后我们可以传递一个数组作为第二个参数。
    • 我需要从 CategoryController 调用像 public function createCategory(User $user, Category $category, string $ability) 这样的方法并传递 action
    • 任何类似的逻辑都可以使用策略过滤器来实现。我会用一个例子来编辑答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 2020-04-20
    • 2019-05-04
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    相关资源
    最近更新 更多