How do I get the page that was denied access by the Auth component using CakePHP 2.x? If I use the referer() function, it gives me the page that linked to the denied action. Here's my code:
public function login() {
//get the current url of the login page (or current controller+action)
$currentLoginUrl = "/login";
if ($this->request->is('post')) {
$this->User->recursive = -1;
$user = $this->User->find(
'first',
array(
'conditions' => array(
'User.username' => $this->request->data['User']['username'],
'User.password' => AuthComponent::password($this->request->data['User']['password'])
)
)
);
if ($user && $this->Auth->login($user['User'])) {
//if the referer page is not from login page,
if( $this->referer() != $currentLoginUrl )
//use $this->referer() right away
$this->redirect($this->referer('/admin', true)); //if referer can't be read, or if its not from local server, use $this->Auth->rediret() instead
else
//if the user lands on login page first, rely on our session
$this->redirect( $this->Session->read('beforeLogin_referer') );
}
else
$this->Session->setFlash('Username or password is incorrect', 'default', array('class' => 'alert-danger'));
}
if( $this->referer() != $currentLoginUrl )
//store this value to use once user is succussfully logged in
$this->Session->write('beforeLogin_referer', $this->referer('/admin', true) ) ; //if referer can't be read, or if its not from local server, use $this->Auth->rediret() instead
}
So basically what happens is I'm not logged in, and I'm at this url:
'http://localhost/hotelguide/hotels/view/17/'
and I click on a link that would take me to
'http://localhost/hotelguide/hotels/review/17/'
but that requires a user to be logged in, so it redirects me to the login page, which, when I debug referrer(), it gives me this:
'http://localhost/hotelguide/hotels/view/17/'
What am I doing wrong?
When you use Auth component in CakePHP and try to access a restricted site, it redirects you to login page and saves the referring page in session. Session key Auth.redirect holds the value you're looking for - the page that you were trying to access.
Look at the __unauthenticated() method of AuthComponent. It includes the code responsible for writing session value to Auth.redirect. If you don't want to use AuthComponent, you can check how it is implemented in the component and write your own solution based on the method I have mentioned.
$this->referer() will not provide you the correct referrer url for you. If you want to get referrer url just use $this->Session->read('Auth.redirect');
You can find exact url you are looking for by $this->Session->read('Auth.redirect');
$this->referer() value update every time when you reload the page.
Related
So I made the application so every time I try to visit a page on it it redirects me to login, thats good, but after I log in I want it to redirect me to a certain page, but it doesnt, it just sends me back to page it redirected me from. I used the code from CakePHP cookbook for login:
public function login()
{
$this->request->allowMethod(['get', 'post']);
$result = $this->Authentication->getResult();
if ($result->isValid()) {
$redirect = $this->request->getQuery('redirect', [
'controller' => 'Buslines',
'action' => 'index',
]);
return $this->redirect($redirect);
}
if ($this->request->is('post') && !$result->isValid()) {
$this->Flash->error(__('Invalid username or password'));
}
}
Now all I need to know is how do I redirect to buslines/index after login.
You are explicitly requesting the redirect query variable and use it for redirection, so what you're seeing is the expected behavior, as that query variable contains the previously visited endpoint where access was denied. The second argument, the default value, will never be used unless the redirect query variable somehow gets lost.
Note that this redirect is only for when authentication was successful, so if you always want to redirect to a fixed endpoint after successful authentication, then just pass the corresponding value directly to redirect(), eg:
return $this->redirect([
'controller' => 'Buslines',
'action' => 'index',
]);
You also don't have to configure the authentication service's queryParam option then.
I am using Symfony 3.1 and angularjs. I would like to redirect the users to a login page when the session expires. However, when I delete a session and click on one of the ng-click button in my view, symfony actually redirects to the loginAction in LogInController. However, it does not render the login page.
public function loginAction(Request $request)
{
error_log('Here in login');
// get access to authentication utilities
$authenticationUtils = $this->get('security.authentication_utils');
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
// render login.html.twig
return $this->render(
'security/login.html.twig',
array(
// last username entered by the user
'last_username' => $lastUsername,
'error' => $error,
)
);
}
This is the network tab after clicking the ng-click button after deleting the session.
I want to record a user's last login, so I'm doing some fairly standard things. In my UsersController:
if ($this->Auth->login()) {
$this->User->id = $this->Auth->user('id');
$this->User->saveField('last_login', date(DATE_ATOM));
$this->Session->setFlash('Yay!'));
$this->redirect( $this->Auth->redirectUrl() );
}
Also, I have set 'autoRedirect' => false in my AppController, which is required so the data will save. The problem is, the user is not taken back to the page they were on, before they went to the login page.
What happens is, the login page thinks for some reason that the referrer was the login page, which results in the user getting kicked back to the "home page" of my app.
I'm mystified. How can I ensure that on log in, the user is taken to the page they were on prior to going to the login screen, with 'autoRedirect' => false?
This seems to be the most reliable approach.
The link to the login page:
echo $this->Html->link('Login', '/login?redirect='.$this->here);
In the login form:
echo $this->Form->input('redirect', array('type' => 'hidden', 'value' => $this->request->query['redirect']));
In the login action in the controller
if (isset($this->request->data['User']['redirect'])) {
$this->redirect( $this->request->data['User']['redirect'] );
} else {
$this->redirect( $this->Auth->redirectUrl() );
}
my UserController.php has logout function that looks like this
function logout()
{
$this->Session->destroy('User');
$this->Session->setFlash('You\'ve successfully logged out.');
var_export($this->Session->read('User'));
//$this->redirect('login');
}
my view Users/index.ctp
<?php echo $this->Html->link('Logout', array('controller' => 'users', 'action' => 'logout')); ?>
When I click "log out" the var_export still displays all the User data and if I go back to Users/index.ctp it still shows me that page even though in my my UserController.php I am checking if User is set
function beforeFilter()
{
$this->__validateLoginStatus();
}
function __validateLoginStatus()
{
if($this->action != 'login' && $this->action != 'logout')
{
if($this->Session->check('User') == false)
{
$this->redirect('login');
}
}
It does not redirect to login page and just brings me to index page.
}
$this->Session->destroy();
The destroy method will delete the session cookie and all session data stored in the temporary file system.
User to remove, use better delete.
$this->Session->delete('User');
If you use the AuthComponent to authenticate the users, you can log them out by using the logout() method.
$this->Auth->logout();
See http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#logging-users-out for Cake 2 or http://book.cakephp.org/1.3/en/view/1262/logout for Cake 1.3
And if you don't use the AuthComponent at all, you should maybe have a look at it as it contains out of the box many functionalities that you have already or will likely implement yourself.
Where is the best place to insert the code to save the user's last login? I am using the CakePHP Auth login system in almost the standard implementation in the manual.
Where can I insert the code so that it will save to the User record just before Auth redirects after login?
You need to disable AuthComponent::autoRedirect if you wish for the code in your UsersController::login() method to execute:
public $components = array(
'Auth' => array(
// ...
'autoRedirect' => false,
),
);
You can then do this in your login action, but you will still need to perform the redirect manually:
public function login() {
if ($this->Auth->user()) { // check user is logged in
$this->User->id = $this->Auth->user('id'); // target correct record
$this->User->saveField('last_login', date(DATE_ATOM)); // save login time
$this->redirect($this->Auth->redirect()); // redirect to default place
}
}