2

我正在制作一个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甚至没有达到update方法,CategoryPolicy.php 因为即使方法总是返回 true 它也不起作用:

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

        return true;
    } 

该方法以任何方式viewAny按预期工作。

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

4

2 回答 2

4

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
于 2020-12-28T21:56:50.213 回答
0

很难看出哪里出了问题,因为它也可能是中间件和 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-12-28T22:07:05.967 回答