Laravel JSON:API 如何限制用户仅能创建关联自身的地址资源
限制用户仅能创建自身关联的地址(Laravel Policy实现)
你可以通过在Policy的create方法中注入Request实例,直接校验请求中的user_id是否与当前请求用户ID一致,无需自定义控制器动作。
修改后的AddressPolicy代码
use Illuminate\Http\Request; class AddressPolicy { use HandlesAuthorization; public function update(User $requestingUser, Address $address): bool { return $requestingUser->is($address->user) || $requestingUser->can('edit addresses'); } public function create(User $requestingUser, Request $request): bool { // 先验证基础创建权限 if (!$requestingUser->can('create addresses')) { return false; } // 获取请求中的user_id,校验是否匹配当前用户ID $requestedUserId = $request->input('user_id'); // 若请求未传入user_id,默认允许(后续可自动填充) if (is_null($requestedUserId)) { return true; } return $requestingUser->id === (int)$requestedUserId; } }
额外优化方案
- 自动填充user_id(推荐):在控制器的
store方法中直接关联当前用户,避免前端传递user_id,从根源杜绝错误:
public function store(Request $request) { $validated = $request->validate([ 'street' => 'required|string', 'city' => 'required|string', // 仅校验地址相关字段,无需user_id ]); // 通过用户关联关系创建地址,自动填充user_id $address = $request->user()->addresses()->create($validated); return new AddressResource($address); }
- 表单请求增强校验:若需允许前端传递
user_id,可在表单请求类中自动填充并校验:
class StoreAddressRequest extends FormRequest { public function authorize() { return $this->user()->can('create', Address::class); } public function rules() { return [ 'user_id' => 'nullable|integer|exists:users,id', // 其他地址字段规则 ]; } protected function prepareForValidation() { // 未传入user_id时自动填充当前用户ID if (!$this->has('user_id')) { $this->merge(['user_id' => $this->user()->id]); } } }
内容的提问来源于stack exchange,提问作者RonnyKnoxville
相关产品推荐
相关产品推荐

