Ok this is the scenario:
If I delete cookies stored however before logging in as a normal user, login works as expected. Another strange thing I have noticed is that the admin redirect in my login function is not actually ran when the normal user logs so they are being redirected elsewhere.
Here is some code:
Users Controller:
<?php
public function login() {
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->Auth->login()) {
//if login successful update logged in User as login does not use recursive find
$this->User->id = $this->Auth->user('id');
$this->User->read();
$this->Auth->login($this->User->data);
if($this->Login->isRole($this->Auth->user(), 'Admin')) {
//redirect admins to admin page, not ran when error occurs!!
$this->redirect(array('controller' => 'users', 'action' => 'index', 'admin' => true));
} else {
//isAuthorised in AppController takes care of redirect to registration page if required
$this->redirect($this->Auth->redirect());
}
} else {
//if login unsuccessful
$this->Session->setFlash(
__('Invalid username or password, please try again.'),
'alert',
array(
'plugin' => 'TwitterBootstrap',
'class' => 'alert-error'
)
);
}
}
//set layout
$this->layout = 'not_logged_in';
//set title
$this->set('title_for_layout', 'Login');
}
public function logout() {
//logout
$this->redirect($this->Auth->logout());
}
public function isAuthorized($user) {
if(parent::isAuthorized($user)) {
//call parent method for redirect and admin permission
return true;
}
switch ($this->action) {
case 'add':
case 'resetPassword':
case 'login':
//logged in users cannot access registration, login or password reset pages
return false;
break;
case 'add_role':
//check user is finshing registration or has a role request accepted
return (!$this->Login->isRegistrationComplete($user) || $this->Login->isRoleRequestAccepted($user));
break;
default:
//all loogged in users can access the rest of User controller
return true;
break;
}
}
php?>
App Controller:
<?php
public $components = array(
'Session',
'Auth' => array(
'className' => 'UserAuth',
'loginRedirect' => array('controller' => 'users', 'action' => 'view'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
'authorize' => array('Controller'),
'authenticate' => array('Blowfish'),
'authError' => 'Please login.',
'loginError' => 'Invalid Username or Password entered, please try again.',
),
'Login'
);
public function isAuthorized($user) {
//set values needed for all logged in pages
$this->set('loggedIn', $user);
$this->set('role', $user['User']['role']);
if($this->Login->isAccessing($this, 'users', 'logout')) {
//never prevent user from logging out
return true;
}
if($this->Login->isRole($user, 'Admin')) {
//admin can access every action
return true;
} elseif ($this->request->prefix === 'admin') {
//only admins allowed on admin pages
throw new Exception('You do not have permission to access this page.', 1);
}
//get user role and requested role
$roles = $this->Login->getRolesCurrentAndNew($user);
if($this->Login->isRoleRequestAccepted($user)) {
//user has an accepted role request
$controller = 'users';
$action = 'add_role';
if($this->Login->isRedirectRequired($this, $controller, $action)) {
//if user is already accessing registration this check prevents redirect loops
if ($this->Login->isRegistrationComplete($user)) {
//display flash based on registration status
$this->Session->setFlash(
__('Your request for the role of '. strtolower($roles['new']) . ' has been accepted, please enter additional details.'),
'alert',
array(
'plugin' => 'TwitterBootstrap',
'class' => 'alert-success'
)
);
} else {
$this->Session->setFlash(
__('Please complete your registration.'),
'alert',
array(
'plugin' => 'TwitterBootstrap',
'class' => 'alert-success'
)
);
}
$this->redirect(array('controller' => $controller, 'action' => $action));
}
} elseif (!$this->Login->isRegistrationComplete($user)) {
//user has not registered yet and role request is not accepted
if(!$this->Login->isRegistrationComplete($user)) {
//user has not completed registration yet, awaiting approval
throw new Exception('Your registration request is awaiting approval from a member of the admin team.', 1);
}
}
return false;
}
?>
Routes config:
Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
Router::connect('/logout', array('controller' => 'users', 'action' => 'logout'));
Router::connect('/register', array('controller' => 'users', 'action' => 'add'));
Router::connect('/register/role', array('controller' => 'users', 'action' => 'add_role'));
Router::connect('/', array('controller' => 'users', 'action' => 'view'));
Router::connect('/admin', array('controller' => 'users', 'action' => 'index', 'admin' => true));
Router::connect('/users/manageRoleRequest', array('controller' => 'roleRequests', 'action' => 'add'));
I eventually realised that CakePHP automatically takes you to the last page you were viewing when you log out and in on the same machine, regardless of whether or not you're logging in as a different user or not.
From the docs:
property AuthComponent::$logoutRedirect
The default action to redirect to after the user is logged out. While AuthComponent does not handle post-logout redirection, a redirect URL will be returned from AuthComponent::logout(). Defaults to AuthComponent::$loginAction.
Meaning:
$this->Auth->logout()
will return a string url. Nothing more. You wrap it with a redirect to redirect to this url:
public function logout() {
$this->redirect($this->Auth->logout());
}
So, no, Cake will only redirect you to the specific action you specified via "loginRedirect" setting. In your case your login view.
I tried the following and it seemed to work for me
public function logout() {
$logout_redirect = $this->Auth->logout();
$this->Auth->redirectUrl($this->Auth->redirect());
return $this->redirect($logout_redirect);
}