CakePHP: Как потребовать роль администратора для определенной страницы?

Мы используем компонент Auth. В настоящее время мы можем запретить пользователям, не вошедшим в систему, посещать нашу страницу «администратора» (adminhome.ctp). Но мы не можем понять, как сделать так, чтобы isAuthorized() запретил посещение страницы и пользователям, не являющимся администраторами.

Внутри AppController:

public function beforeFilter() {
    $this->Auth->allow('index', 'view', 'login', 'logout', 'display');
    $this->Auth->authorize = array('Controller'); 
    //$this->Auth->autoRedirect = false;
}

public function isAuthorized($user_id) {
    $this->loadModel('User');
    $user = $this->User->findById($this->Auth->user());
    if ( $user['User']['role'] === 'admin') {
        $this->Session->setFlash('isAuthorized');
        return true;
    }
    $this->Session->setFlash('!isAuthorized');
    return false;
}

Здесь beforeFilter() в PagesController:

function beforeFilter() {
    $this->Auth->deny('adminhome');
}

Что мы делаем не так?


person emersonthis    schedule 25.04.2013    source источник


Ответы (3)


Я считаю, что ваш способ не работает, потому что вы должны использовать Auth->deny() для ограничения доступа к методам, а adminhome не является методом в PagesController. Попробуй это:

# in app/controller/PagesController.php
public function display() {
  $page = empty($this->request->params['pass'][0]) ? null : $this->request->params['pass'][0];
  if($page == 'adminhome' || $this->User->isAuthorized()) {
    $this->render($page);
  } else {
    # redirect the user somewhere else
  }
}

Надеюсь, это поможет

person vcanales    schedule 26.04.2013
comment
Мы используем административную маршрутизацию. Он отлично работает на всех контроллерах, но, похоже, не применим к страницам, потому что, как вы указали, «adminhome» не является методом. Я попробую вашу версию, но я не понимаю, как она решит мою конкретную проблему, связанную с конкретной страницей, отображаемой PagesController. Другими словами, $this->Auth->deny() не может ссылаться на конкретную страницу, не так ли? - person emersonthis; 26.04.2013
comment
Я предполагаю, что меня смущает ваш ответ, потому что первый блок (с использованием префиксов администратора, как нам хотелось бы), похоже, вообще не ссылается на страницы. - person emersonthis; 26.04.2013
comment
Не обращайте внимания на первую часть ответа, если вы уже используете маршрутизацию администратора. И да, $this-›Auth-›deny(), вероятно, не может ссылаться на определенные страницы, поэтому вам нужно использовать методы display() и isAuthorized() в вашем случае, как я указал во второй части. - person vcanales; 26.04.2013
comment
Я на самом деле отредактирую это, так как это не относится к вашему вопросу. - person vcanales; 26.04.2013
comment
Я понимаю. Должна ли эта функция display() возвращать функцию по умолчанию, которая появляется в этом файле из коробки? Я никогда не видел функции, определенной со строковым параметром. - person emersonthis; 26.04.2013
comment
Извините, я действительно сильно запутался в ответе, я как бы шел по памяти. Я отредактировал его сейчас с тем, что я действительно использую. Вы должны проверить, какая страница запрашивается в первую очередь, поэтому параметр в действии display() был далеко. - person vcanales; 26.04.2013
comment
Должен ли оператор быть && вместо ||? - person emersonthis; 26.04.2013
comment
@devJunk У меня похожая проблема. Что конкретно представляет проходная часть массива? $this-›request-›params['pass'][0] ? - person user1104854; 29.04.2013

Я только что использовал арийский ответ, однако внес некоторые незначительные изменения, которые могут быть полезны для других:

if($this->Session->read('Auth.User.role') != 'admin')
    {
        $this->Session->setFlash('You are not authorized to visit this page');
        $this->redirect('/');
    }
person Nichs    schedule 28.03.2015

У вас будет поле роли в пользовательской таблице. В конкретном действии добавьте эту строку

if($this->Session->read('Auht.User.role') != 'admin') {
      ...............................
} 

Если вы хотите, чтобы только администратор мог видеть все действия в каком-либо контроллере, таком как admincontroller

вы можете добавить этот код в этот контроллер в действии beforeRender

if($this->Session->read('Auth.User.role') != 'admin')
            {
                $this->Session->setFlash(You are not authorized to visit this page,'flash',array('alert'=>'info'));
                $this->redirect('/');
            }
person Aryan    schedule 19.10.2013