Как скрывать поля api в зависимости от разрешения пользователя?

В Laravel есть несколько способов скрыть поля в сериализованной форме ресурсов API в зависимости от разрешения пользователя. Вот некоторые из них:

  1. Использование концепции "скрытых" атрибутов (Hidden Attributes):
  • В вашей модели определите свойство $hidden, в котором перечислите имена полей, которые вы хотите скрыть. Например:
     protected $hidden = ['api_token', 'password'];
  • Поля, перечисленные в $hidden, не будут показаны при сериализации модели в JSON.
  1. Использование фракталов (Fractals):
  • Устанавливаем пакет Fractal через Composer:
     composer require league/fractal
  • Создайте трансформатор (Transformer) для вашей модели с помощью Fractal. В методе transform можно задать логику фильтрации полей API, исходя из прав доступа пользователя. Например:
     use LeagueFractalTransformerAbstract;
     
     class UserTransformer extends TransformerAbstract
     {
         public function transform(User $user)
         {
             $data = [
                 'id' => $user->id,
                 'name' => $user->name,
                 'email' => $user->email,
             ];
             
             if (auth()->user()->can('view-api-token')) {
                 $data['api_token'] = $user->api_token;
             }
             
             return $data;
         }
     }
  • Возвращаемую модель (например, User) передаем в трансформатор для сериализации.
  1. Использование ресурсов API (API Resources):
  • В Laravel 5.5 и выше есть новая функциональность - ресурсы API (API Resources).
  • Создайте ресурс API для вашей модели. В методе toArray реализуйте логику фильтрации полей API, исходя из прав доступа пользователя. Например:
     use IlluminateHttpResourcesJsonJsonResource;
     
     class UserResource extends JsonResource
     {
         public function toArray($request)
         {
             $data = [
                 'id' => $this->id,
                 'name' => $this->name,
                 'email' => $this->email,
             ];
             
             if (auth()->user()->can('view-api-token')) {
                 $data['api_token'] = $this->api_token;
             }
             
             return $data;
         }
     }
  • Возвращаемую модель (например, User) передаем в ресурс API для сериализации.
  1. Использование Laravel-Passport:
  • Если вы используете пакет Laravel Passport для аутентификации и авторизации API, вы можете использовать метод withHidden для скрытия полей, которые пользователь не имеет права просматривать.
  • В вашем AuthServiceProvider добавьте определение политики доступа для поля API Token. Например:
     Gate::define('view-api-token', function ($user, $model) {
         return $user->id === $model->id;
     });
  • Затем, при сериализации модели пользователю, используйте метод withHidden в контроллере или маршруте:
     return $user->withHidden(['api_token'])->toJson();
  1. Использование пакета "Laravel Hidden Traits":
  • Устанавливаем пакет через Composer:
     composer require peanutbutterbrains/laravel-hidden-traits
  • Вместо использования $hidden в модели, вы можете использовать трейт PeanutButterBrainHiddenTraitsHiddenTrait. Просто добавьте его в вашу модель.
  • Затем укажите, какие поля должны быть скрыты в зависимости от разрешения пользователя, используя метод addHiddenProperty($permission, $property). Например:
     use IlluminateDatabaseEloquentModel;
     use PeanutButterBrainHiddenTraitsHiddenTrait;
     
     class User extends Model
     {
         use HiddenTrait;
         
         protected $hidden = ['api_token', 'password'];
         
         public function __construct(array $attributes = [])
         {
             parent::__construct($attributes);
             $this->addHiddenProperty('view-api-token', 'api_token');
         }
     }
  • В данном примере поле api_token будет скрыто, если у пользователя нет разрешения view-api-token.

Все эти подходы могут быть использованы в зависимости от ваших потребностей и требований вашего проекта. Выберите наиболее подходящий для вас вариант, учитывая сложность вашей системы разрешений и требуемую гибкость.