Caducidad de la sesión solo si hay inactividad (IDLE)

Issue #78 new
Ramón Menor created an issue

Sería interesante tener un campo en la configuración que indicara el tiempo en el que caduca la sesión si no haces ninguna actividad, pero que nunca caduque si estas trabajando. El problema es que a veces se me caduca la sesión en el momento de estar grabando algún dato.

Comments (9)

  1. Cristian Salazar repo owner

    Hola ramón, esto que mencionas se relaciona con IDLE, es decir, "que hacer mientras nada ocurre".

    Eso es algo que le compete al diseño de tu aplicación, como veras en los ejemplos que he puesto mas abajo. Será muy dificil y peligroso para todo el mundo el hecho de que el gestor de sesiones no se cierre si hay actividad, razon: un usuario malicioso vendrá y te mantendrá una sesion abierta por meses si gusta usando un robot, o intentando violar claves con un robot adivinador. Es muy duro saber cuando forzadamente eliminarse una sesion, cómo saber si es un jakeo o un proceso legitimo ?

    ejemplo:

    CASO 1: el caso crudo en donde ocurre el bug en tu sistema debido a un corte de sesion entre medio de un proceso atomico. en este caso la accion termina en excepcion porque tu modelo en alguna regla ha detectado que no hay usuario, aun cuando al empezar si lo habia.

    public function actionRestarStock(){
       if(Yii::app()->user->isGuest)
          return;
       // le queda menos de un segundo de vida de sesion
      $model = new StockEntry();
       $model->reduceStockCausedByUser(Yii::app()->user->id);
       if(!$model->save()){ // ha muerto la sesion en medio de esto.
            throw new Exception("su sesion ha caducado.");
       }
    }
    

    CASO 2 - solucion #1 salvando info vital en un stack y culminando proceso bien, haciendo que el proceso atomico no se vea afectado, eliminando eso si cualquier regla en "el modelo" la cual haga el trabajo de detectar sesiones, cosa que no le compete al modelo sino al controller.

    public function actionRestarStock(){
       if(Yii::app()->user->isGuest)
          return;
      $curUserId = Yii::app()->user->id;
      $curUserName = Yii::app()->user->name;
      $model = new StockEntry();
       $model->reduceStockCausedByUser($curUserId, $curUserName);
       if(!$model->save()){
            throw new Exception("otro error, nada que ver con sesion.");
       }
    }
    

    CASO 3 - asegurando que al cerrar el proceso no haya muerto la sesion asegurandose asi que no se haga nada si el proceso atomico es interrumpido, igualmente al caso2 eliminando cualquier regla en el modelo que se ponga a verificar sesiones, tarea que le compete solo al controller.

    public function actionRestarStock(){
       if(Yii::app()->user->isGuest)
          return;
      $tr = Yii::app()->db->beginTransaction();
      $curUserId = Yii::app()->user->id;
      $curUserName = Yii::app()->user->name;
      $model = new StockEntry();
       $model->reduceStockCausedByUser($curUserId, $curUserName);
       $model->save();
       if(Yii::app()->user->isGuest){
           $tr->rollback();
        }else{
            $tr->commit();
        }
    }
    
  2. Cristian Salazar repo owner

    de todos modos, le enviare la invitacion a ricardo andres obregón a ver que opina de esto, no me gusta ser unilaterlal, porque puedo equivocarme pero lo primero que veo al "cerrar una sesion solo si hay IDLE" es una perfecta ocasión de hacking para ese sistema y todo aquel que opere asi.

  3. Cristian Salazar repo owner

    Ramon propone un "permiso de holding", el usuario que tenga ese permiso asignado, mediante un rol especial asignado podria ser, entonces, al caducar la sesion del lado del servidor, verificar que no tenga el rol especial de holding asignado, y entonces actuar en consecuencia.

  4. Rick O'Brien

    Ramón y Christian, creo que es muy subjetivo pensar en en el significado de "trabajar", porque si estoy "trabajando" podría ser en la aplicación web o en otra cosa (por ejemplo: usar algún procesador de palabra)... recordando que el browser no puede detectar ni medir si hay actividad externa o en otra página web (a menos que haya alguna aplicación del escritorio que haga ese trabajo de notificar a la aplicación web que sí se está trabajando o ya se está AUSENTE). Si eventualmente se necesita hacer algo a nivel de web es en el evento "mouseMove" poner una especie de ping que notifique a la aplicación web.

    Se dicho de paso que si estoy trabajando en Mi Aplicación web la sesión no caducará (con la configuración pode defecto de PHP).

    Si definitivamente se necesita algo que mida si está Ausente o no el PC, entonces es necesario un desarrollo en otro lenguaje (C/C++, Lazarus, Python, etc) que se comunique con el sistema operativo (X, Windows, Mac, etc) y que a su vez envíe una notificación a la aplicación. (Sea dicho de paso que algunas aplicaciones Windows-only usan ActiveX para este propósito, pero hoy en día si dejé de trabajar cierto tiempo en la aplicación se cierra la sesión, por ejemplo, el email, GDocs, etc)

  5. Ramón Menor reporter

    Y que os parecería una función que se ejecute después de que el usuario haga algo y que haga un reset de la fecha inicial de login. Me explico: el usuario entra y se le da una fecha de entrada que permite calcular el tiempo que puede tener abierta la sesión, mientras el usuario este pulsando enlaces y trabajando automáticamente esa fecha de entrada se va actualizando con lo que el tiempo de sesión comienza a contar a partir del último click que ha hecho, es decir cuando ya no hace nada en la aplicación. Así parecería que la sesión se mantiene abierta indefinidamente pero en realidad caduca después de un tiempo.

  6. Ramiro Anacona Meneses

    Tambien le pregunte esto a Chrisitian, no es nada amigable para el usuario, que aun al estar trabajando en la aplicacion web se cerro la session por que si, la propuesta de Ramon Menor es la que me parece una buena opcion.

  7. Ramón Menor reporter

    Mi solución actual que estoy probando es actualizar el tiempo de expiración en el beforeAction como si hubiesemos hecho login en ese instante. Luego configuro la variables del sistema en 30 min. Así se que cada vez que paso de una página a otra de ejecuto una acción ajax se incrementará mi tiempo de sesión en 30 min. En el caso de que fuera una aplicación de pasarse más tiempo escribiendo un texto o realizando una tarea que no fuera pulsar una acción podríamos solucionarlo poniendo más tiempo de sesión o bien en esa vista concreta una función que ejecutara en action via ajax (por ejemplo para guardar el documento).

    El caso es que lo estoy probando y no se si funcionaría bien en todos los casos.

    /*
         * Antes de que se ejecute una acción
         */
        public function beforeAction($action) 
        {
            //Yii::log(__METHOD__ . ' isGuest: ' . (Yii::app()->getUser()->isGuest ? 'Si' : 'No'));
    
            // Cada vez que se ejecuta una acción se actualiza el tiempo de expiración
            // TODO: integrar con cruge o mejorar
            $sys = Yii::app()->user->um->getDefaultSystem();
            $duration = $sys->getn('sessionmaxdurationmins');
            // Encuentra la última sesión y actualiza la fecha de expiración
            $model = CrugeSession::model()->findLast(Yii::app()->user->id);
            if ($model != null) {
                $model->expire = CrugeUtil::makeExpirationDateTime($duration);
                $model->save();
            }
    
            return true;
        }
    

    Esta función la pongo en Controller que es un componente desde el que se extiende el resto de controllers.

  8. Debie

    Ok... quiero dar mi opinion al respecto. Supongamos que yo quiero darle permiso a mis usuarios para que esten un tiempo limitado de tiempo en el programa, ponte en el caso de que tengan que llenar formularios largo, que podrian tardar 3 o 4 horas en llenarlo... Ok, pongo tiempo de caducidad de la sesion en 5 horas, pero que pasa si el usuario se va y deja su sesion abierta?? cualquier persona puede venir y en cinco horas hacer desastres en la data... es seguro eso??... por lo tanto, deberia haber un tiempo de caducidad de la sesion en el caso de que efectivamente quisieramos evitar que un software malicioso mantenga la sesion abierta y otro margen de caducidad para cerrar sesion por inactividad!!!.

  9. Log in to comment