CakePHP 2.x:为什么我的/ admin / user / login卡在重定向循环中?

时间:2015-12-09 07:03:36

标签: cakephp admin cakephp-2.x

我创建了一个带有管理部分的小项目。我正在使用管理员路由重定向到我的控制器中的管理员操作。该网站的页面可供所有人使用,无需登录。要访问/ admin或/ admin / users等,您必须登录。

我已将管理操作传播到我的控制器,例如“admin_login”,“admin_users”,...

所以我的问题是,当有人进入/ admin / users或其他管理页面时,如果用户在会话中,我必须检查每个控制器操作,否则重定向到登录表单。

有没有办法在一个地方做到这一点?我在AppController类中使用了一个beforefilter。

当使用这样的东西时,我得到一个无限循环:

AppController.php

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)进行正面登录。

UsersController.php

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));
    }
}  

1 个答案:

答案 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,使你的生活变得困难。我建议你研究一下这个话题:

相关问题