#laravel #laravel-backpack
#ларавель #laravel-рюкзак #laravel #laravel-backpack
Вопрос:
Я использую laravel-backpack admin для раздела администрирования моего приложения, а также я использую PermissionManager
для управления ролями и разрешениями пользователей. Теперь я хочу назначить конкретный доступ к конкретным данным.
например, представьте, что у нас есть система управления статьями, а также у нас есть editor
роль и связанные с ней разрешения для пользователя, имя пользователя которого user24
, поэтому желаемый способ заключается в том user24
, чтобы получить доступ к определенным статьям, например article 1
, в их панели мониторинга или списке crud.
Articles
структура таблицы:
ПРИМЕЧАНИЕ: поле ‘user_id’ указывает на владельца статьи.
|---------------------|------------------|------------------|
| id | title | user_id |
|---------------------|------------------|------------------|
| 1 | article1 | 2 |
|---------------------|------------------|------------------|
Ответ №1:
Подход 1:
Один из способов добиться этого — создать второй класс с именем CrudArticle
(или что-то еще), расширить исходный класс Article, но затем добавить глобальную область видимости к этой модели, которая ограничивает все запросы к таблице с использованием класса, включая только записи, принадлежащие текущему пользователю. Используйте этот класс с вашей панелью CRUD и классом normal 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%, что только вышеуказанное защитит от вставок (запросов post непосредственно к конечной точке обновления), т. Е. Вам все равно может потребоваться изменение для «UpdateRequest», рекомендованного во втором возможном решении ниже
Подход 2:
Другой способ добиться этого — изменить запросы, используемые 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;
}
В качестве альтернативы вы можете добавить глобальную область видимости к рассматриваемой модели, как описано здесь, хотя я стараюсь избегать этого, поскольку это меняет поведение во всем приложении
Комментарии:
1. Спасибо за ваш ответ, но упомянутое
user_id
поле относится к владельцу статьи, поэтому я хочу назначить доступ другим пользователям, которые не являются владельцем статьи.2. @MeysamZarei Хм, я не уверен, что понимаю, как там используется, однако применяется тот же принцип, вы просто измените условия на те, которые вам нужны.
3. Вы правы. Я искал библиотеку или что-то еще для этого, чтобы сделать это хорошо, но я ничего не нашел. Итак, как вы сказали, это кажется подходящим принципом, и мне кажется, что я должен справиться с упомянутой проблемой.