我创建了一个带有管理部分的小项目。我正在使用管理员路由重定向到我的控制器中的管理员操作。该网站的页面可供所有人使用,无需登录。要访问/ admin或/ admin / users等,您必须登录。
我已将管理操作传播到我的控制器,例如“admin_login”,“admin_users”,...
所以我的问题是,当有人进入/ admin / users或其他管理页面时,如果用户在会话中,我必须检查每个控制器操作,否则重定向到登录表单。
有没有办法在一个地方做到这一点?我在AppController类中使用了一个beforefilter。
当使用这样的东西时,我得到一个无限循环:
class AppController extends Controller {
public $helpers = array('Paginator','Acl.AclHtml');
public $components = array('Acl', 'Session',
'Auth' => array(
'authError' => 'You are not authorized to access that location.',
'authorize' => array(
'Actions' => array(
'actionPath' => 'controllers')
),
'controllers' => array('users')
));
public function beforeFilter() {
if(isset($this->request->prefix) && ($this->request->prefix == 'admin')){
$username = $this->Session->read('Admin.username');
if (empty($username)) {
$this->redirect (array(
'controller'=>'users',
'action'=>'login',
'admin'=>true
));
} else {
$this->redirect (array(
'controller'=>'admin',
'action'=>'dashboard',
'admin'=>true
));
}
}
// LDAP
$server_ip = $_SERVER['SERVER_ADDR'];
$ldapIp = ClassRegistry::init('LdapIp');
$ldapIpCount = $ldapIp->find('count', array('conditions' => array('ldap_ip' => $server_ip)));
if ($ldapIpCount >= 1) {
$this->Auth->authenticate = array('Ldap');
} else {
$this->Auth->authenticate = array('Form');
}
$this->Auth->authenticate = array('Form');
$this->Auth->allow();
if (!$this->Auth->isAllow($this)) {
$this->set(array(
'message' => array(
'text' => __('un aunthaticated request'),
'type' => 'error',
'status' => "401"
),
'_serialize' => array('message')
));
throw new ForbiddenException();
}
}
}
使用LDAP(Active Directory)进行正面登录。
App::uses('AppController', 'Controller');
App::uses('Sanitize', 'Utility');
class UsersController extends AppController {
public $components = array('Paginator', 'Session', 'RequestHandler', 'Auth', 'Acl');
public function admin_login() {
$this->layout = 'admin_login';
if ($this->request->is('post')) {
$username = $this->request->data['User']['username'];
$password = $this->request->data['User']['password'];
$password = Security::hash($password, null, true);
$logged_in = $this->User->find('count', array('conditions' => array('User.username' => $username, 'User.password' => $password, 'User.role' => 'Admin', 'User.active' => 1)));
if ($logged_in >= 1) {
$this->Session->setFlash(__('Login successful!'), 'default', array('class' => 'alert alert-success'));
$users = $this->User->find('first', array('conditions' => array('User.username' => $username, 'User.password' => $password, 'User.role' => 'Admin', 'User.active' => 1)));
$this->Session->write('Admin.id', $users['User']['id']);
$this->Session->write('Admin.username', $users['User']['username']);
$this->Session->write('Admin.group_id', $users['User']['group_id']);
$this->Session->write('Admin.full_name', $users['UserProfile']['fname'] . " " . $users['UserProfile']['lname']);
$this->redirect(array('controller' => 'admin', 'action' => 'dashboard', 'admin' => true));
} else {
$this->Session->setFlash(__('Username or password is incorrect!'), 'default', array('class' => 'alert alert-error'));
}
}
}
public function admin_logout() {
$this->Session->delete("Admin");
//$this->Session->destroy();
$this->Session->setFlash(__('Logged out successful!'), 'default', array('class' => 'alert alert-success'));
$this->redirect(array('controller' => 'users', 'action' => 'login', 'admin' => true));
}
}
答案 0 :(得分:0)
Yoy正在获得无限循环,因为当您尝试访问beforeFilter()
时会调用/admin/users/login
。
处理您需求的正确方法是设置Auth Component。
设置组件后,在UsersController::beforeFilter()
中,您必须允许通过allow()
方法访问不需要登录的操作。 E.g。
public function beforeFilter() {
$this->Auth->allow(array('signup'));
parent::beforeFilter();
}
这也适用于任何其他具有非登录用户需要访问的操作的控制器。
您将自动允许在Auth组件配置中定义的loginAction
。
在blog tutorial中,您将找到Auth组件使用的一个很好的示例。
如上所述,即使您尝试访问AppController::beforeFilter()
,也始终会调用/admin/users/login
。要防止这种情况发生,请尝试添加以下条件:
if (empty($username) && $this->action!='login') {
$this->redirect (array(
'controller'=>'users',
'action'=>'login',
'admin'=>true
));
}
如果您允许AuthComponent
为您处理身份验证,则不需要这样做。
但是,无法保证您的代码能够按预期工作。你没有充分利用AuthComponent
,使你的生活变得困难。我建议你研究一下这个话题: