#php #graphql #lumen #laravel-lighthouse
#php #graphql #lumen #laravel-lighthouse
Вопрос:
У меня есть приложение, которое позволяет использовать несколько пользователей. Каждый пользователь полностью изолирован друг от друга; это означает, что все, что не является пользователем в базе данных, имеет 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
}
Опять же, это работает, но обязательно ли это должно быть ad hoc, как это, или есть способ получше?
Комментарии:
1. промежуточное программное обеспечение для аутентификации??
2. Я изучил это, но я действительно не знаю, что бы я с этим сделал. Я уже использую его для аутентификации пользователя
3. просто проверьте это, возможно, его можно использовать вместо функций, с более детальным контролем прав на разных уровнях
Ответ №1:
Я думаю, что ваше решение в порядке, оно экономит на написании целой кучи шаблонов. Несколько незначительных предложений:
Вы можете превратить свой признак в загрузочный признак, который автоматически вызывается фреймворком, переименовав boot
метод в bootHasOwnerTrait
.
Возможно, стоит рассмотреть возможность сделать isOwner
область активной по умолчанию. В Laravel это ошибочно называется глобальной областью. Это позволяет вам не указывать область видимости явно, хотя вы все равно можете опустить это, если у вас есть некоторые запросы, к которым это не должно применяться, например, статистика.
Комментарии:
1. Это отличный совет. Если бы я сделал область видимости глобальной, есть идеи, как бы я опустил это позже, если мне понадобится?
2.
MyModel::withoutGlobalScope('isOwner')