Должна ли авторизация быть частью модели или контроллера? - PullRequest
25 голосов
/ 31 августа 2011

Я пишу веб-приложение с некоторыми требованиями ACL: пользователь может вносить изменения в некоторые элементы, некоторые элементы могут редактироваться несколькими пользователями, администратор может редактировать что угодно, а менеджер может редактировать все в своей организации и т. Д.

Я использую Play!В соответствии с каркасом, и, судя по виду модуля Secure, кажется, что место, где можно поставить проблемы авторизации, находится в контроллерах.Тем не менее, мне кажется, что вопросы авторизации являются частью бизнес-логики и, следовательно, должны быть в модели.Кроме того, я начинаю видеть дублированную логику в контроллерах, которую мне нужно реорганизовать.

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

Так что же является обычной практикой?Могу ли я добавить код авторизации в модель или оставить его в контроллере?

Ответы [ 6 ]

16 голосов
/ 31 августа 2011

Я думаю, что это серая зона. Можно утверждать, что доступ пользователя является частью отображения между миром HTTP и объектно-ориентированным миром. Это то, для чего предназначен контроллер (отсюда и интенсивное использование статики) для преобразования входящего запроса, готового к обработке бизнес-правил в доменной модели.

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

6 голосов
/ 01 сентября 2011

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

Не думаю, что безопасность должна выполняться на уровне контроллера.

На мой взгляд, это должно выглядеть так:

Вид -> Контроллер -> Безопасность -> Модель

Уровень безопасности может быть фасадом или прокси-сервером над моделью, защищающим доступ, но прозрачным для контроллера.

Однако, если представления должны быть изменены в зависимости от прав доступа пользователя, могут потребоваться некоторые проверки на уровне контроллера (например, установка значения логического свойства CanEdit в ViewModel).

4 голосов
/ 25 ноября 2014

Авторизация не должна быть частью контроллера или модели домена.

Вместо этого она должна находиться на уровне службы.

Контроллер должен просто действовать как диспетчер и делегировать между HTTP и службой приложений.Это сервис приложений, где происходит оркестровка.Это лучшее место для размещения авторизации.

Предположим, что пользователь A авторизован для доступа к данным из домена X, но не авторизован даже для доступа на чтение данных из домена Y. Если авторизация размещена в контроллере, топользователь A авторизуется в контроллере X, и через сервисные вызовы может получить доступ к данным из домена Y, что не соответствует ожиданиям.

Поскольку модели доменов взаимодействуют друг с другом на уровне обслуживания, следовательно, лучше разместитьавторизация на том же уровне.

1 голос
/ 23 октября 2017

Из моего личного опыта работы с фреймворками MVC я бы сказал:

  1. Модель - это объект, представляющий таблицу базы данных. чистый и не должен содержать никакой дополнительной логики.
  2. Контроллер - это место, где принимаются решения и др. Пользовательская логика, поэтому авторизация должна быть в контроллере. Это может быть разработан какой-то крючок, который может проверить, авторизован ли пользователь или не во всех необходимых местах, поэтому у вас не будет повторения кода СУХОЙ.

  3. Лучший способ дать разрешение пользователю, если вы используете типичный REST архитектура состоит в том, чтобы создать токен, сохранить его в базе данных и на стороне клиента и проверяйте этот токен при каждом запросе. Если вы используете приложение веб-браузера, вы можете использовать сеансы на стороне сервера для авторизации ( Это намного проще).

Поэтому я предлагаю сохранить логику авторизации в контроллере.

1 голос
/ 23 октября 2017

Я нахожусь на этом этапе и намереваюсь обработать это следующим образом:

  • Нет проверки формы JS, вместо этого через HTTPS ajax

  • Ajax php class

  • Данные формы, отправляемые в модель в качестве данных для конкретной проверки для
    общего типа, такого как электронная почта и пароль (вероятная проверка массива сопоставления будет использоваться повторнодругие классы, так что это определенно область модели).

  • если нет ошибок, поиск в таблице User учетных данных электронной почты /
    учетных данных пароля, передаваемых контроллеру с аутентификацией
    тип, такой как логин / регистрация / сброс пароля

  • , затем контроллер создает требуемое представление вывода или устанавливает пользователя, вошедшего в сеанс и т. Д.

Это основано на Laravel, но у меня есть своя собственная библиотека, так как я хочу, чтобы она была независимой от laravel и просто свободно основывалась на этом жизненном требовании.

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

1 голос
/ 01 сентября 2011

Мне лично очень нравится способ игры! Защищенный модуль справляется с этим ( учебник здесь всегда полезен ). Если вы не возражаете против использования аннотации @Before, это довольно безболезненно.

...