Laravel 策略总是 returns 403 未经授权
Laravel Policy Always returns 403 unauthorized
我正在制作一个使用 jwt
作为身份验证系统的应用程序,
当我尝试更新我的 Category
模型时,政策总是 returns 403 未授权,
我正在使用 apiResource
来 crud
我的模型。
我的代码
在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
方法都按预期工作。
I'm using axios to fetch and update data and I'm sending the request with the bearer token
and every thing is working ok except the issue above.
在CategoryController.php
中,而不是注入$id
:
public function update(Request $request, $id)
尝试注入类型提示模型实例:
public function update(Request $request, Category $category)
并删除 find()
命令:
//$category = Category::find($id);
生成新控制器时,您还可以使用此 artisan 命令在函数参数中包含类型提示模型。
php artisan make:controller CategoryController --api --model=Category
很难看出哪里出了问题,因为它也可能是中间件和 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.
}
}
我正在制作一个使用 jwt
作为身份验证系统的应用程序,
当我尝试更新我的 Category
模型时,政策总是 returns 403 未授权,
我正在使用 apiResource
来 crud
我的模型。
我的代码
在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
方法都按预期工作。
I'm using axios to fetch and update data and I'm sending the request with the
bearer token
and every thing is working ok except the issue above.
在CategoryController.php
中,而不是注入$id
:
public function update(Request $request, $id)
尝试注入类型提示模型实例:
public function update(Request $request, Category $category)
并删除 find()
命令:
//$category = Category::find($id);
生成新控制器时,您还可以使用此 artisan 命令在函数参数中包含类型提示模型。
php artisan make:controller CategoryController --api --model=Category
很难看出哪里出了问题,因为它也可能是中间件和 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.
}
}