Laravel политики: как сделать так, чтобы вести себя "от имени" - PullRequest
0 голосов
/ 29 мая 2020

Возможно, это вопрос о том, как Laravel работает внутри

Я пишу приложение. Только зарегистрированный пользователь может создавать определенные типы записей, это просто, вы просто добавляете $this->middleware('auth') к контроллеру, и все.

Теперь я хочу что-то более сложное, пользователи с ролью admin могут создавать / редактировать такие записи от имени какого-либо пользователя. Представьте себе что-то вроде StackOverflow, где пользователь может редактировать вопрос, заданный другим пользователем, но для создания. Вот и все, администратор может создать сообщение от имени пользователя ():

Итак, у меня есть мой create() в моем PronController, это что-то вроде:

function create($sid, $uid=NULL) {
    // $sid is section id, where the post is going to be created... don't mind...

    // if $uid (user id) is null, it will take the user from Auth::user()->id
    $user = empty($uid) ? Auth::user() : User::findOrFail($uid);

    // I want that only "admin" can use this $uid parameter, so I plan to use
    // a Policy:
    $this->authorize('create', $user);        
}

Политика в PronPolicy довольно проста:

function create(User $authUser, User $user) {
    return ($authUser->id === $user->id) || $authUser->isAdmin;
}

Я думал, что это должно работать, но это не так. Он никогда не достигает этого edit() (я разместил журнал)

Итак, я изменил строку $this->authorize() на:

$this->authorize('createpron', $user);

И изменил UserPolicy() (UserPolicy !!!) на:

function createpron(User $authUser, User $user) {
    return ($authUser->id === $user->id) || $authUser->isAdmin;
}

Теперь это работает так, как я хотел. Но не знаю почему. Похоже, что Laravel ищет тип объекта в параметре, а затем активирует политику для этого параметра, это правильно?

Я не знаю, хотя мой код работает, он кажется мне немного грязным, так как создание «Pron» должно быть политикой Pron, а не пользователя. Я делаю что-то концептуально неправильно? как правильно это реализовать?

1 Ответ

1 голос
/ 29 мая 2020

Похоже, что Laravel ищет тип объекта в параметре, а затем активирует политику для этого параметра, это правильно?

Правильно! В документах упоминается это :

Политики - это классы, которые организуют авторизацию logi c вокруг конкретной модели или ресурса . Например, если ваше приложение представляет собой блог, у вас может быть модель Post и соответствующая PostPolicy для авторизации действий пользователя, таких как создание или обновление сообщений.

Передавая $user аргумент для $this->authorize(), вы спрашиваете, может ли текущий пользователь предпринять действия против этой конкретной записи.

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

Начните с разделения авторизации. У вас действительно есть две отдельные, но связанные проверки разрешений:

  1. Может ли текущая User действовать от имени другого User?
  2. Может ли конечный пользователь (текущий или от имени) создать Pron?

# 1 можно ввести как либо Шлюз, либо Политика, в зависимости от того, хотите ли вы передать от имени User часть проверки. Это было бы полезно, если, скажем, вы можете действовать от имени пользователей только в своей организации. UserPolicy будет подходящим местом для этого.

# 2 будет реализован так, как если бы у вас не было никаких функций от имени. Так что, возможно, это просто return true, потому что их может создать кто угодно, или все, что требуется вашему приложению для возможности создания Pron.

Затем введите их отдельно.

function create($sid, $uid = null)
{
    $user = Auth::user();

    if (!empty($uid)) {
        $user = User::findOrFail($uid);

        $this->authorize('on-behalf-of', $user);
    }

    $this->authorizeForUser($user, 'create', new Pron());

    // Continue your create logic...
}

Некоторые преимущества, которые это дает:

  • Контроллер немного более явно читает, какие действия авторизации происходят и как они связаны
  • Шлюзы и политики не t должны в такой степени полагаться на смешивание типов записей и могут строго сравнивать разрешение с указанным пользователем без аргументов. по-прежнему не могу создавать сообщения)

Возможные обратные стороны:

  • Противоположно более жестким элементам управления, указанным выше: если вы хотите, чтобы объединял проверки разрешений по порядку чтобы изменить их, это не совсем решает эту проблему. Например, пользователь X не может создавать сообщения, но если администратор действует от его имени, он МОЖЕТ, вышеуказанное не совсем решает эту проблему
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...