2010-06-12 1 views
4

В настоящее время я пишу приложение, в котором у меня есть несколько пользователей. У них есть данные, которые должны быть видны только им, а не другим пользователям, прошедшим проверку подлинности в системе. У меня также есть администраторы, которые управляют системой и имеют доступ ко всей информации. Каков наилучший способ ограничить пользователей данными без ограничения пользователей?Как ограничить данные для пользователей, которые владеют им, не ограничивая пользователей admin в CakePHP?

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

Например, я хочу, чтобы стандартный пользователь мог видеть только свою информацию об пользователях и ограничиваться только операциями CRUD. Однако администратор должен иметь возможность видеть ВСЕ пользователя и данные пользователя CRUD ALL. Есть идеи?

+0

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

+1

Я добавил новое решение, которое может быть полезно. И только потому, что решение недоступно, это не значит, что это «вне темы». –

ответ

0

После того, как я не нашел то, что искал в Интернете, и не получил решение, размещенное здесь (скорее всего, из-за моей неспособности сообщить то, что я искал), я провел последние несколько дней, написав решение. У меня наконец есть решение, которое я ищу. Хотя некоторые из ответов здесь были на пути записи, они просто недостаточно полны для того, что я искал.

Поскольку здесь недостаточно места для публикации результатов, я добавил контент в свой блог. Вы можете подготовить его здесь по адресу blogchuck.com. Пожалуйста, не стесняйтесь взорвать его на куски, это поможет нам всем в долгосрочной перспективе.

Спасибо всем, кто нашел время для публикации.

+0

Ваше сообщение в блоге больше не доступно, есть ли у вас другая ссылка? –

0

Вы можете получить информацию о текущем пользователе this way:$this->Auth->user(). Вы можете использовать идентификатор группы пользователей в своем обратном вызове, чтобы ограничить запрос. Также возьмите добычу на WhoDidIt Behavior.

+0

Это, по-видимому, подход «глобального пользователя». Мои пользователи ADMIN находятся в $ this-> Auth так же, как и пользователи STANDARD. Но группа не всегда находится в данных. Например, если у меня есть пользователь, добавляющий книги, идентификатор группы не будет находиться в таблице BOOK. Но каждый пользователь должен иметь возможность просматривать только свои книги. Админы должны иметь возможность видеть ВСЕ книги. Я не уверен, что вы поделитесь, даже будет работать. Мне не нужно отслеживать обновления пользователем, мне нужно ограничить доступ к данным. –

+0

Если вы будете использовать поведение WhoDidIt, у вас будет идентификатор пользователя (который создал запись) в таблице BOOK в столбце 'created_by'. Если пользователь вошел в систему, должен быть идентификатор пользователя и идентификатор группы в '$ this-> Auth-> user()'. Если '$ this-> Auth-> user ('id')' совпадает с 'created_by' или когда' $ this-> Auth-> user ('group_id') 'is 'admin', запись разрешена. – bancer

3

Понадобится:

  • Информация о текущем пользователе
  • Информация об элементе в вопросе

Вы комбинировать их с чем-то вроде этого (простой пример):

$user = $this->Auth->user(); 
$book = $this->Book->find(…); 
if ($user['type'] != 'admin' && $user['id'] != $book['Book']['creator_id']) { 
    $this->Session->setFlash("You're not allowed to view this item"); 
    $this->redirect('somewhere'); 
} 

Вы можете сделать способ в своей модели, например

function userCanAccessItem($item, $user) 

для централизации логики проверки доступа и вызова его из контроллера.

Еще лучше, если вы используете Cake's admin routing, вы можете опустить все проверки в действиях admin_ и применять обычную проверку привилегий пользователя в доступных для пользователя действиях.

Вы также можете посмотреть ACLs для более мелкого контроля доступа.

+0

Спасибо за ответ. Это похоже на другой ответ, уже предоставленный. Но опять же, ['type'] не задано с помощью Auth. Это что-то мне нужно делать вручную или переопределить? Я использую админ-маршрутизацию, поэтому у меня возникают трудности. Если я, например, поставил обратный вызов в модели (что кажется лучшим способом сделать это, как это можно сделать глобально), то те же ограничения будут применяться и к администраторам. Это по-прежнему не похоже на самый очевидный «торт» способ сделать это. –

+0

@cdburgess Я считаю, что информация '$ this-> Auth-> user()' просто хранится в '$ this-> Session-> read ('Auth')'. Вы можете написать любую дополнительную информацию, необходимую для разрешения типа пользователя там во время входа в систему. Вы не должны ставить аутентификацию пользователя в обратном вызове модели, поскольку это серьезно ограничивает гибкость модели. Аутентификация - это что-то сделано в контроллере. – deceze

+0

можно ли управлять доступом на уровне строк с помощью ACL? – RSK

0

Для любого другого, кто приходит сюда, это то, как я его настраивал.

Сначала я создал basic Role based ACL

Тогда я запретить доступ к reports/all для обычных пользователей

$config['rules']['deny'][reports/all'] = 'Role/default' ; 

Тогда в модели, которые я хотел защитить добавил я это:

public function beforeFind($queryData){ 
    //TODO:make this cleaner 
    App::uses('ComponentCollection', 'Controller'); 
    App::uses('AclComponent', 'Controller/Component'); 
    $collection = new ComponentCollection(); 
    $this->Acl = new AclComponent($collection);  

    if(!$this->Acl->check(array('User'=>AuthComponent::user()),'/reports/all/')){ // must be a user (not admin) 
     $this->bindModel(array('hasOne' => array('ReportsUser'))); 
     $queryData['conditions']['ReportsUser.user_id'] = AuthComponent::user('id'); 
     $queryData['recursive'] = 2; 
    } 
    return $queryData; 
} 

В случаях, когда ACL не разрешает доступ к reports/all, мы добавляем условие к любым поисковым запросам, поэтому оно отображает только отчеты с правильным user_id ,

+0

Это довольно ужасно по двум причинам: во-первых, используя компонент в модели, второй и, что более важно, - ** (db) acl - очень плохой выбор **, чтобы обратиться к «Как ограничить данные для пользователей, которые владеют им, не ограничивая админ пользователей». Если неясно, почему, подумайте, сколько записей аро, aco и разрешений должно существовать для миллиона пользователей и миллиона продуктов - для выражения правила _one_. – AD7six

+0

Во-первых, как я уже сказал в другом месте, нет другого способа получить доступ к информации ACL от модели, отличной от ACLComponent. Во-вторых, вы, кажется, пропустили то, что я рекомендовал использовать ACL на основе роли. Тогда у вас есть только 2 ARO, «admin» и «user», а затем у вас есть только 1 ACO «Отчеты/все». Также я не рекомендовал ** db acl **, а скорее ** phpAcl **. Очевидно, вы могли бы просто «if (AuthComponent :: user ('role») ==' admin ') ... ', но если у вас есть пользователи-администраторы, вам, вероятно, нужна другая активность типа ACL. –