【问题标题】:Laravel Policy Always returns 403 unauthorizedLaravel 政策总是返回 403 未授权
【发布时间】:2021-04-05 14:59:16
【问题描述】:

我正在制作一个使用jwt 作为身份验证系统的应用,

当我尝试更新我的 Category 模型时,策略总是返回 403 未授权,

我正在使用apiResourcecrud 我的模型。

我的代码

api.php:

Route::apiResource('category', CategoryController::class);

CategoryController.php:

    public function update(Request $request, $id)
    {
        // print_r($request->all());
        $validator = Validator::make(
            $request->all(),
            [
                'name' => 'required|min:2|unique:categories,name,' . $request->id,
                'description' => 'required|min:1',
            ],
            [
                "name.unique" => "اسم الصنف مستخدم مسبقا",
                "name.required" => "اسم الصنف مطلوب",
                "name.min" => "اسم الصنف يجب أن يحتوي على حرفين على الأقل",

                "description.required" => "وصف الصنف مطلوب",
            ]
        );
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->messages(), 'status' => 422], 200);
        }
        $category = Category::find($id);
        $category->name = $request->name;
        $category->description = $request->description;
        $category->save();
        return response()->json([
            "message" => "تم تحديث الصنف",
            "status" => 200
        ], 200);
    }

CategoryPolicy.php:

    public function update(User $user, Category $category)
    {

        return $category->user_id === $user->id;
    }

似乎request 甚至没有达到CategoryPolicy.php 中的update 方法 因为即使方法总是返回 true 它也不起作用:

    public function update(User $user, Category $category)
    {

        return true;
    } 

viewAny 方法按预期工作。

我正在使用 axios 来获取和更新数据,我正在使用 bearer token 发送请求,除了上述问题之外,一切正常。

【问题讨论】:

标签: laravel laravel-authentication laravel-authorization laravel-jwt


【解决方案1】:

CategoryController.php,而不是注入$id

public function update(Request $request, $id)

尝试注入类型提示的模型实例:

public function update(Request $request, Category $category)

并删除find() 命令:

//$category = Category::find($id);

在生成新控制器时,您还可以使用此工匠命令在函数参数中包含类型提示模型。

php artisan make:controller CategoryController --api --model=Category

【讨论】:

  • 这肯定会使代码更干净,但是是什么让您认为它可以解决问题中概述的问题?
  • @miken32 我不久前遇到了这个问题,并通过这样做解决了。控制器中似乎没有类型提示,模型无法正确注入策略函数
【解决方案2】:

很难看出哪里出了问题,因为它也可能是中间件和 JWT 令牌。您可以做的是在您的更新方法中检查用户是否已登录,将以下内容添加为方法的第一行。如果为 false,请检查您的 JWT 实现

dd(auth()->check());

我还建议清理你的控制器:

class CategoryController
{
    /**
     * CateogryController constructor.
     */
    public function __construct()
    {
        $this->authorizeResource(Category::class); // if your are using CRUD, validate like this
    }

    /**
     * Update specific resource.
     *
     * @param Category $category
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(Category $category, CategoryRequest $request): JsonResponse
    {

// notice the model route binding. 
        $this->authorize('update', $category); // If you only have update method, but remove the __construct.

        $category->update([
            'name' => $request->get('name'),
            'description' => $request->get('description')
        ]);

        return response()->json(['message' => 'تم تحديث الصنف']); // take the 200 from the headers, not add it in as text. 
    }

}

您的请求与此类似:

class CategoryRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true; // you could consider to validate the user->category relation. I like it more separated and put it in a separated policy.
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|min:2|unique:categories,name',
            'description' => 'required|min:1',
        ];
    }

    /**
     * @return string[]
     */
    public function messages()
    {
        return [
            "name.unique" => "اسم الصنف مستخدم مسبقا",
            "name.required" => "اسم الصنف مطلوب",
            "name.min" => "اسم الصنف يجب أن يحتوي على حرفين على الأقل",
            "description.required" => "وصف الصنف مطلوب",
        ];
    }
}

您的政策如下:

class CategoryPolicy
{
    use HandlesAuthorization;

    /**
     * Determine if the user can update category resource.
     *
     * @param User $user
     * @param Category $category
     * @return bool
     */
    public function update(User $user, Category $category): bool
    {
        return $user->categories()->where('id', $category->id)->exists(); // or somthing like this.
    }
}

【讨论】:

    猜你喜欢
    • 2020-11-14
    • 2018-10-24
    • 2021-03-23
    • 2021-12-24
    • 1970-01-01
    • 2020-04-19
    • 2018-01-07
    • 2020-06-26
    • 1970-01-01
    相关资源
    最近更新 更多