cakephp login redirect

2020-08-01 06:51发布

I have a user front end and an admin area. If a user is signed in and trys to go to the to the admin url they are redirected to the index page. I wish to redirect them to the admin login page with a message to login as administrator.

There may be a case where a admin is logged in as a user and then trys to login into the admin area. I have not been able to rediect to the admin login and give option to log out and log in as admin.

app_controller

function beforeFilter() {

    $this->Auth->loginError = "Wrong credentials";
    $this->Auth->authError = "This part of the website is protected.";

    //Configure AuthComponent   
    $this->Auth->allow('display');
    $this->Auth->authorize = 'actions';
    $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
    $this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
    //$this->Auth->autoRedirect = false;
    //$this->Auth->loginRedirect = array('controller' => 'reservatins', 'action' => 'index');


} // end before filter

users_controller

function beforeFilter() {
    parent::beforeFilter();
    $this->Auth->allowedActions = array('admin_login','admin_logout');
    //$this->Auth->allowedActions = array('*');
    $this->set('select_nav', array('admin','users'));

}


function admin_login() {
    // $this->layout = 'admin'; // nothing required
    $this->layout = 'blank'; // nothing required
}

标签: cakephp
1条回答
▲ chillily
2楼-- · 2020-08-01 07:40

I have done that on one of my projects. The user is ever logged in (as Anonymous, as User or as Admin) and, depending on from where is he coming, and the current permissions he have, I show different login errors.

To do that.. this is what I did...

First, you need to use the "controller" authorize method:

$this->Auth->authorize = 'controller';

From now on, all your actions will pass through the isAuthorized method of your current controller. As I have my users, groups and permissions on my database and every group have different permissions, I created the isAuthorized method on my app_controller:

public function isAuthorized()
{
    if ( !$this->__permitted($this->name, $this->action) )
    {
        $this->cakeError('error403');
        return false;
    }
    return true;
}

What I'm doing here is checking for user permissions through my AppController __permitted method (it simply checks for permissions on session; if we don't have them saved in session, I check for them on the DB and then I store them on the Session).

If the user don't have permissions, I show him the error 403. And here is the funny part.

In your AppError add a method called error403, and here you can control where to redirect the user and what kind of message to show to him.

Here is the code I've used (obviously you must create your own piece of code according to your needs):

public function error403()
{
    // Extract params
    extract($this->controller->params, EXTR_OVERWRITE);

    // Store url to be redirected on success
    if (!isset($url))
    {
        $url = $this->controller->here;
    }
    if (isset($url['url']))
    {
        $url = $url['url'];
    }
    $url = Router::normalize($url);

    // The page is trying to access is an admin page?
    $is_admin_page = isset($this->controller->params['admin']) && $this->controller->params['admin'] == true ?  true : false;

    if (!empty($url) && count($url) >= 2)
    {
        $query = $url;
        unset($query['url'], $query['ext']);
        $url .= Router::queryString($query, array());
    }
    // 403 header
    $this->controller->header("HTTP/1.0 403 Forbidden");

    // If my method is NOT an upload
    if (!preg_match('/upload/', $url))
    {
        // Write referer to session, so we can use it later
        $this->controller->Session->write('Auth.redirect', $url);
    }
    else exit; // else exit, so we prevent 302 header from redirect

    // NOTE: we can't use $this->controller->Auth->loginAction because there's no controller loaded
    $loginAction = array('controller' => 'users', 'action' => 'login');

    // If is ajax...
    if (isset($this->controller->params['isAjax']) && $this->controller->params['isAjax'] == true)
    {
        $this->controller->layout = 'ajax';

        $message = __("No tens permisos per fer aquesta acció", true);
        // If user is anonymous..
        if ( $this->controller->ISession->isAnonymous() )
        {
            // AJAX Error Message
            $message = __('La teva sessió no està iniciada.', true) 
                . ' <a href="'.Router::url($loginAction).'">' 
                . __('Fes clic aquí per iniciar-la', true) . '</a>';
        }

        $this->controller->set(compact('message'));
        $this->controller->render('error403');

        $this->controller->afterFilter();
        echo $this->controller->output;
    }
    else
    {
        $message = __("No tens permisos per fer aquesta acció", true);
        $redirect = $this->controller->referer();

        // If is anonymous...
        if ($this->controller->ISession->isAnonymous())
        {
            $message = __('La teva sessió no està iniciada.', true);
            $redirect = $loginAction;
        }
        // If user can't access the requested page, we redirect him to login
        if (!$this->controller->ISession->userCan($redirect))
        {
            $redirect = $loginAction;
        }

        // Show different auth messages for admin and user pages
        $this->controller->Session->setFlash($message, $is_admin_page ? 'default' : 'gritter', array(), 'auth');
        $this->controller->redirect($redirect, null, true);
    }
}

Remember, this is the code for my case. You should create your own error403 page according to your needs. Of course, you can start with my method to get it :)

查看更多
登录 后发表回答