方法一:
实现此目的的一种方法是创建第二个名为CrudArticle(或其他)的类,使其扩展原始 Article 类,然后向此模型添加一个全局范围,将所有查询限制为使用该类的表仅包括属于当前用户的记录。将此类与您的 CRUD 面板和应用程序中其他地方的普通 Articles 类一起使用。
class CrudArticle extends Article {
public static function boot()
{
parent::boot();
// only include models that belong to this user
$user_id = 0;
Auth::check();
if ($user = Auth::user()) {
$user_id = $user->id;
}
static::addGlobalScope('userFilter', static function (Builder $builder) use ($user_id){
$builder->where('user_id', $user_id);
});
}
}
注意:这将防止非拥有记录出现在列表页面上,并防止通过直接 url 加载编辑页面。但是,我不能 100% 确定仅上述内容就可以防止插入(将请求直接发布到更新端点),也就是说,您可能仍然需要更改下面第二种可能的解决方案中推荐的“UpdateRequest”
方法二:
实现此目的的另一种方法是修改 CRUD 使用的查询,例如,在您的 CRUD 控制器中:
/**
* Set up the "list" or "read" operation for the resource
*/
public function setupListOperation(): void
{
// ... normal setup code ...
Auth::check();
$user = Auth::user();
if (!$user) {
throw new \Exception('Unauthorized');
}
$this->crud->query = $this->crud->query->where('user_id', $user->id);
}
为了防止通过直接 url 查看更新页面,您可以在 setupUpdateOperation 中添加如下内容:
/**
* Set up the "update" operation for the resource
*/
public function setupUpdateOperation(): void
{
// ... normal setup code ...
$authorized = false;
// only allow viewing the update page if the user is logged in and owns the Article
Auth::check();
if ($user = Auth::user()) {
$id = $this->get('id');
$product = Article::find($id);
if ($product) {
$authorized = $product->user_id === $user->id;
}
}
if (!$authorized) {
$this->crud->denyAccess(['update']);
}
}
为防止未经授权的编辑直接发布到更新端点,您还需要在 UpdateRequest 中添加如下内容:
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
$authorized = false;
// only allow updates if the user is logged in and owns the Article
Auth::check();
if ($user = Auth::user()) {
$id = $this->get('id');
$product = Article::find($id);
if ($product) {
$authorized = $product->user_id === $user->id;
}
}
return $authorized;
}
或者,您也可以add a global scope to the model in question as explained here,但我倾向于避免这样做,因为它会改变整个应用程序的行为