4

I have problems with a session variable, users log into the app and then it sets a session variable but when it redirects to the next controller it isn't there.

At the moment I am not using the auth component, I think it is not correct, but I don't know how to apply it to my logic. This is because I dont log in users with username and password, they come authenticated from other website that gives me a ticket and a key to know who they are.

Here is my code of the UsersController where the app starts:

class UsuariosController extends AppController {
public $components = array('Session');

function beforeFilter() {

}

function login() {
    $isLogged = false;
    if(!empty($_POST['Ffirma']) ) {
        $this->loginByTicket();
    }
    else if(!empty($this->data)) { //When users log by email it works perfectly
        $this->loginByEmail();
    }
}

private function loginByEmail() {
    //Se busca el usuario en la base de datos
    $u = new Usuario();
    $dbuser = $u->findByEmail($this->data['Usuario']['email']);

    //if doesn't exist user in db
    if(empty($dbuser) ) {
        $this->Session->setFlash('El usuario no existe en el sistema, consulte con el administrador.');
        $this->redirect(array('controller' => 'usuarios', 'action' => 'login'));
        exit();
    }
    $this->userIsCorrectlyLogged($dbuser);
}

function loginByTicket() {
    $Fip = $_POST['Fip'];
    $Frol = $_POST['Frol'];
    $FidPersona = $_POST['Fidpersona'];
    $Fticket = $_POST['Fticket'];
    $Ffirma = $_POST['Ffirma'];
    //Check sing
    $f = $this->gen_firma($Frol, $FidPersona,  $Fticket);
    if( strcmp($f, $Ffirma) != 0 ) {
        $this->Session->setFlash('Firma no válida.');
        return;
    }
    //Check if ticket is valid
    //1º Check if it exists on the db
    $t = split('-',$Fticket);
    $ticket = new Ticket();
    $dbticket = $ticket->findById($t[0]);
    if( strcmp($dbticket['Ticket']['valor'], $t[1]) != 0) {
        $this->Session->setFlash('Ticket no válido.');
        return;
    }

    //2º if Ip ok
    if($Fip != $dbticket['Ticket']['ip']) {
        $this->Session->setFlash('IP no válida.'.' '.$dbticket['Ticket']['ip'].' '.$Fip);
        return;
    }

    $u = new Usuario();
    $dbuser = $u->findById($dbticket['Ticket']['idPersona']);
    $this->userIsCorrectlyLogged($dbuser);
}

private function userIsCorrectlyLogged($dbuser) {
    $user = array('Usuario' => array(
        'last_login' => date("Y-m-d H:i:s"),
        'rol_app' => 1,
        'nombre' => $dbuser['Usuario']['nombre'],
        'email' => $dbuser['Usuario']['email'],
        'apellidos' => $dbuser['Usuario']['apellidos'],
        'id' => $dbuser['Usuario']['id']
    ) );
    //Some stuff to determine rol privileges
    $this->Session->destroy(); 
    $this->Session->write('Usuario', $user);
    $this->redirect(array('controller' => 'mains', 'action' => 'index'),null, true);
    exit();
}

As you can see I make some controls before know that the user is correctly logged, and in user correctly logged I just save the session.

In my AppController I check if the user has logged in, but the session variable has already gone:

class AppController extends Controller {
    public $components = array('Session');
    function beforeFilter() {
        //Configure::write('Security.level', 'medium'); //I've tried this that i saw somewhere
        pr($this->Session->read()) // Session is empty
        if($this->checkAdminSession()) {
            $user = $this->Session->read('Usuario');
            $email = $user['Usuario']['email'];
            $usuario = new Usuario();
            $dbuser = $usuario->findByEmail($email);
            $respons = $usuario->getAccionesResponsable($dbuser['Usuario']['id']);  
            $this->set("hayacciones", true);
            if( empty($respons) ) $this->set("hayacciones", false);
        }
        else {
           $this->Session->setFlash('Necesitas identificarte para acceder al sistema.');

           $this->redirect('/usuarios/login/');
           exit();
        }
}
    function checkAdminSession() {
        return $this->Session->check('Usuario');        
    }
}

I'm desperate, I've read a lot of documentation but I don't know how to solve this problem, could you give me any clue?

Thanks you very much, and sorry for my English!.

Note: I have discovered that if the security level is low it works:

Configure::write('Security.level', 'low');

But I dont like this solution...

NewRehtse
  • 338
  • 1
  • 5
  • 15
  • Similar: http://stackoverflow.com/questions/22079477/cakephp-session-is-lost-after-an-oauth-redirect – trante Feb 27 '14 at 21:12

5 Answers5

4

I was losing session information after a login call too and after searching for a while I found many different ways to fix my issue. I only regret that I don't fully understand what is causing the issue, but I imagine it has to do with php's session configuration.

  1. As you mentioned, changing Security.level to low fixed the issue for me Configure::write('Security.level', 'low');
  2. Changing the session save configuration to php fixed the issue for me too: Configure::write('Session', array( 'defaults'=>'cake', ));
  3. And finally adding a timeout worked too (which I ended up using): Configure::write('Session', array( 'defaults'=>'php', 'cookieTimeout'=> 10000 ));

All these found in /app/Config/core.php

I post this hoping someone is able to make sense of what is going on underneath. I feel understanding the root of the issue would make a better job of answering your question.

andreshernandez
  • 226
  • 1
  • 7
4

You are overriding the beforeFilter() method. So, instead of using this:

<?php
class UsuariosController extends AppController {

    function beforeFilter() {

    }

you should do this:

<?php
class UsuariosController extends AppController {

    function beforeFilter() {
        parent::beforeFilter();
    }
fzmaster
  • 388
  • 2
  • 5
2

I have the same problem. I tried all the suggestion. My Cache engine is Apc.

  $this->__saveData($t);
  debug($this->Session->read());// >>>>>> GOOD
  $this->redirect(array('controller'=>'users','action'=>'main'));
    }
}
 }
  function logout() {
    $this->Session->destroy();
            $this->Session->delete('User');
    $this->redirect(array('controller'=>'logins','action'=>'login'));
}
function forgot() {
$this->layout = 'login';

} 
    private function __saveData($t)
    {   
         $this->Session->write('User',$t['User']['name']);
         $this->Session->write('User_name',$t['User']['firstname']);
         $this->Session->write('User_id',$t['User']['id']);
         $this->Session->write("User_Group",$t['Group']['name']);
         $g = $this->Myauth->getPerm('User_Group'); // This is the array of permission w.r.t to the menu (key)
         $this->Session->write("Permissions",$g);

         debug($this->Session->read());
    }
 function main()
{
    // Check permissions
$this->Myauth->check('users','login');
$username   = $this->Session->read('User');
debug($this->Session->read( ));die(); <<<<< NOTHING

}

The funny thing is that yesterday it worked.

My php.ini has a simple extension=apc.so. My core.php

    Configure::write('Session.defaults', 'php');

Nothing change if I change the Security level. I will appreciate any direction.

EDIT First solution: in my php.ini I had a bad value for session.referer_check (It was = 0 while it should be ''). But now, on the same server, one site is ok. Another one fires the error Error: Call to undefined function apc_cache_info()

The two sites are separated and do not share any cakelib.

[SOLUTION FOUND]

For Cake > 2.2 and Chrome 24 I found this solution (I tried all the others found on the web). In your core.php:

     Configure::write('Security.cookie', 'cakephpfdebackend');
     Configure::write('Session.cookieTimeout', 0);
     Configure::write('Session.checkAgent', false);
     Configure::write('Session.cookie_secure',false);
     Configure::write('Session.referer_check' ,false);
     Configure::write('Session.defaults', 'php'); 

Actually, only the Session.cookieTimeout is required. The other settings are optional to solve the problem.

gdm
  • 7,647
  • 3
  • 41
  • 71
0

A possible reason for this problem is that the server clock is not synced with the client's clock and thus the cookie timeouts.

0

I had some issue with session on some pages . Can you check whether any space comes at the bottom of page after the php ending tag. When i faced this problem, i found session is missing due to a white space character in controller after the php ending tag . Please check this and let me know .

Kiran
  • 919
  • 6
  • 8
  • Checked: there isn't any space after php ending tag: ?> I've checked models and views invlolved. – NewRehtse Feb 03 '12 at 11:05
  • Are you sure , session is set properly and accessible in some pages . Or all pages missing session ? Can i see the checkAdminSession() body. I think this where session is checking . – Kiran Feb 03 '12 at 11:44
  • At the moment i have only this: function checkAdminSession() { return $this->Session->check('Usuario'); } – NewRehtse Feb 03 '12 at 12:00