Lighthouse GraphQL 数据所有权通过 user_id
Lighthouse GraphQL data ownership via user_id
我有一个允许多个用户的应用程序。每个用户彼此完全隔离;这意味着数据库中不是用户的所有内容都有一个 user_id
列,并且只有登录用户才可以查看、更新或删除它们。此外,用户不能使用其他人的 user_id.
创建行
是否有内置方法可以使用 Lumen/Lighthouse 解决此问题?这是我所做的,并且有效,但我想知道我是否重新发明了轮子:
- 每个模型都有一个
user
关系,像这样:
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- 我给这些模型加了一个
HasOwnerTrait
,内容如下:
public static function boot()
{
parent::boot();
static::creating(function (Model $model) {
$model->user_id = Auth::user()->id;
});
static::saving(function (Model $model) {
if ($model->user_id !== Auth::user()->id) {
$exception = new ModelNotFoundException();
$exception->setModel(self::class, $model->id);
throw $exception;
}
});
static::deleting(function (Model $model) {
if ($model->user_id !== Auth::user()->id) {
$exception = new ModelNotFoundException();
$exception->setModel(self::class, $model->id);
throw $exception;
}
});
}
public function scopeIsOwner($query)
{
return $query->where('user_id', Auth::user()->id);
}
- 最后,在我的架构定义中:
type Query {
recipes: [Recipe!]! @all(scopes: ["isOwner"])
}
type Mutation {
createRecipe(input: CreateRecipeInput! @spread): Recipe @create
updateRecipe(id: ID!, input: UpdateRecipeInput! @spread): Recipe @update
deleteRecipe(id: ID!): Recipe @delete
}
同样,这是有效的,但它是否需要像这样临时设置,还是有更好的方法?
我认为你的解决方案很好,它省去了编写一大堆样板文件。一些小建议:
您可以通过将 boot
方法重命名为 bootHasOwnerTrait
.
使您的特征成为框架自动调用的可引导特征
也许可以考虑使 isOwner
作用域默认处于活动状态。在 Laravel 中,这被混淆地称为 全局范围 。这允许您省略显式命名范围,但如果您有一些不应该应用的查询,您仍然可以省略它,例如统计数据。
我有一个允许多个用户的应用程序。每个用户彼此完全隔离;这意味着数据库中不是用户的所有内容都有一个 user_id
列,并且只有登录用户才可以查看、更新或删除它们。此外,用户不能使用其他人的 user_id.
是否有内置方法可以使用 Lumen/Lighthouse 解决此问题?这是我所做的,并且有效,但我想知道我是否重新发明了轮子:
- 每个模型都有一个
user
关系,像这样:
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- 我给这些模型加了一个
HasOwnerTrait
,内容如下:
public static function boot()
{
parent::boot();
static::creating(function (Model $model) {
$model->user_id = Auth::user()->id;
});
static::saving(function (Model $model) {
if ($model->user_id !== Auth::user()->id) {
$exception = new ModelNotFoundException();
$exception->setModel(self::class, $model->id);
throw $exception;
}
});
static::deleting(function (Model $model) {
if ($model->user_id !== Auth::user()->id) {
$exception = new ModelNotFoundException();
$exception->setModel(self::class, $model->id);
throw $exception;
}
});
}
public function scopeIsOwner($query)
{
return $query->where('user_id', Auth::user()->id);
}
- 最后,在我的架构定义中:
type Query {
recipes: [Recipe!]! @all(scopes: ["isOwner"])
}
type Mutation {
createRecipe(input: CreateRecipeInput! @spread): Recipe @create
updateRecipe(id: ID!, input: UpdateRecipeInput! @spread): Recipe @update
deleteRecipe(id: ID!): Recipe @delete
}
同样,这是有效的,但它是否需要像这样临时设置,还是有更好的方法?
我认为你的解决方案很好,它省去了编写一大堆样板文件。一些小建议:
您可以通过将 boot
方法重命名为 bootHasOwnerTrait
.
也许可以考虑使 isOwner
作用域默认处于活动状态。在 Laravel 中,这被混淆地称为 全局范围 。这允许您省略显式命名范围,但如果您有一些不应该应用的查询,您仍然可以省略它,例如统计数据。