ExtJS 4: Gerenciamento de Sessão: Session Timeout

02/08/2012 | By | 4 Comments

Ei pessoal,

Uma pergunta que recebo bastante por email e nas palestras sobre ExtJS que ministro é: Como fazer gerenciamento de sessão usando ExtJS 4? Bem, nesse post vamos tratar justamente sobre esse assunto através de um exemplo prático!

O exemplo desse post irá mostrar uma mensagem para o usuário perguntando se deseja continuar com a sessão aberta, e caso positivo, a app vai cutucar o servidor para manter a sessão ativa; caso negativo, a app automaticamente faz logout. Essa janela vai ficar 1 minuto aberta; caso o usuário não tome nenhuma decisão, também faz logout. A sessão se torna inativa caso o usuário não tome nenhuma ação em uma quantidade de tempo (exemplo: 15 minutos), isso inclui digitar alguma coisa no teclado ou mexer o mouse:

extjs4 sessiontimeout loiane ExtJS 4: Gerenciamento de Sessão: Session Timeout

A classe que faz toda essa mágica está aqui:

/**
 * Session Monitor task, alerts the user that their session will expire in 60 seconds and provides
 * the options to continue working or logout.  If the count-down timer expires,  the user is automatically
 * logged out.
 */
Ext.define('MyApp.widgets.SessionMonitor', {
  singleton: true,

  interval: 1000 * 10,  // run every 10 seconds.
  lastActive: null,
  maxInactive: 1000 * 60 * 15,  // 15 minutes of inactivity allowed; set it to 1 for testing.
  remaining: 0,
  ui: Ext.getBody(),

  /**
   * Dialog to display expiration message and count-down timer.
   */
  window: Ext.create('Ext.window.Window', {
    bodyPadding: 5,
    closable: false,
    closeAction: 'hide',
    modal: true,
    resizable: false,
    title: 'Session Timeout Warning',
    width: 325,
    items: [{
      xtype: 'container',
      frame: true,
      html: "Your session will automatically expires after 15 minutes of  inactivity. If your session expires, any unsaved data will be lost and  you will be automatically logged out. </br></br>If you want  to continue working, click the 'Continue Working'  button.</br></br>"
    },{
      xtype: 'label',
      text: ''
    }],
    buttons: [{
      text: 'Continue Working',
      handler: function() {
        Ext.TaskManager.stop(MyApp.widgets.SessionMonitor.countDownTask);
        MyApp.widgets.SessionMonitor.window.hide();
        MyApp.widgets.SessionMonitor.start();
        // 'poke' the server-side to update your session.
        Ext.Ajax.request({
          url: 'user/poke.action'
        });
      }
    },{
      text: 'Logout',
      action: 'logout',
      handler: function() {
        Ext.TaskManager.stop(MyApp.widgets.SessionMonitor.countDownTask);
        MyApp.widgets.SessionMonitor.window.hide();

        // find and invoke your app's "Logout" button.
        Ext.ComponentQuery.query('button[action="buttonLogout"]')[0].fireEvent('click');
      }
    }]
  }),

  /**
   * Sets up a timer task to monitor for mousemove/keydown events and
   * a count-down timer task to be used by the 60 second count-down dialog.
   */
  constructor: function(config) {
    var me = this;

    // session monitor task
    this.sessionTask = {
      run: me.monitorUI,
      interval: me.interval,
      scope: me
    };

    // session timeout task, displays a 60 second countdown
    // message alerting user that their session is about to expire.
    this.countDownTask = {
      run: me.countDown,
      interval: 1000,
      scope: me
    };
  },

  /**
   * Simple method to register with the mousemove and keydown events.
   */
  captureActivity : function(eventObj, el, eventOptions) {
    this.lastActive = new Date();
  },

  /**
   *  Monitors the UI to determine if you've exceeded the inactivity threshold.
   */
  monitorUI : function() {
    var now = new Date();
    var inactive = (now - this.lastActive);

    if (inactive >= this.maxInactive) {
      this.stop();

      this.window.show();
      this.remaining = 60;  // seconds remaining.
      Ext.TaskManager.start(this.countDownTask);
    }
  },

  /**
   * Starts the session timer task and registers mouse/keyboard activity event monitors.
   */
  start : function() {
    this.lastActive = new Date();

    this.ui = Ext.getBody();

    this.ui.on('mousemove', this.captureActivity, this);
    this.ui.on('keydown', this.captureActivity, this);

    Ext.TaskManager.start(this.sessionTask);
  },

  /**
   * Stops the session timer task and unregisters the mouse/keyboard activity event monitors.
   */
  stop: function() {
    Ext.TaskManager.stop(this.sessionTask);
    this.ui.un('mousemove', this.captureActivity, this);  //  always wipe-up after yourself...
    this.ui.un('keydown', this.captureActivity, this);
  },

  /**
   * Countdown function updates the message label in the user dialog which displays
   * the seconds remaining prior to session expiration.  If the counter expires, you're logged out.
   */
  countDown: function() {
    this.window.down('label').update('Your session will expire in ' +  this.remaining + ' second' + ((this.remaining == 1) ? '.' : 's.') );

    --this.remaining;

    if (this.remaining < 0) {
      this.window.down('button[action="logout"]').handler();
    }
  }

});

Vamos ver alguns detalhes importantes:

  • linha 11maxInactive – tempo de inatividade do usuário para inativar a sessão. Nesse caso, o valor padrão são de 15 minutos, mas você pode mudar esse valor para a quantidade de tempo que você deseja (em minutos).
  • linha 29: html – mensagem que será mostrada para o usuário na janela. Está em inglês, mas você pode traduzir para português se desejar.
  • linha 42: url – aqui você vai colocar a url para “cutucar” o servidor para manter a sessão ativa no server também.
  • linha 53: aqui colocamos o selector a ser chamado para disparar o evento de logout automaticamente. Nesse exemplo, repare que tem um botão de logout, e essa linha chama exatamente a função que faz logut (nesse exemplo é apenas um alert, mas isso você deve tratar como deseja na sua aplicação). Só um detalhe: não chame a action do seu botão de logut de logout, pois este já está sendo usado por essa classe.

Bem pessoal, é isso!

Se quiser usar essa classe na sua aplicação, basta chamar MyApp.widgets.SessionMonitor.start(). Se estiver usando a arquitetura MVC, coloque isso dentro da função launch da app. No final desse post tem um exemplo de uma app usando essa classe.

Demo (inatividade de 15 segundos – para ninguém ficar esperando muito tempo! rs) : http://loiane.com.br/extjs/extjs4-sessiontimeout/

Código Fonte Completo: https://github.com/loiane/extjs4-session-timeout

Disclaimer: eu não sou autora desse código, portando, qualquer problema reclame nessa thread do fórum da Sencha: http://www.sencha.com/forum/showthread.php?195957-Session-Timeout-Alert-using-PHP-amp-Extjs4

Até a próxima! icon smile ExtJS 4: Gerenciamento de Sessão: Session Timeout

Filed in: Ext JS 4 | Tags: , ,

Comments (4)

  1. Gustavo

    Muito bacana ^^

    Não entendi muito bem o “linha 42: url”, seria tipo verificar num arquivo PHP se o usuario ainda ta ativo?

    • Oi Gustavo,
      Como o ExtJS fica separado do lado server, esse exemplo é para verificar se o usuário está inativo. Mas acontece que o server side também tem timeout, e esse request ajax serve apenas para “acordar” o server também.
      []‘s

  2. Olá, Loiane. Não sei se isso funciona na prática, pois como ex. tenho um server com tomcat e sua sessão está marcada para expirar com 10min, ai o usuário faz login no sistema e fica na sessão do tomcat o user logado, para dar acesso as páginas internas, enquanto ele ficar interagindo com o server sua sessao ficará ativa, mas se ele passar mais de 10min sem interagir com o server ela vai cair, ou seja, o codigo acima marca a interação com o client, então suponto que ele ate mexa no mouse ou fique em um cadastro grande (ex. venda de produtos) quando ele for fazer um interação com o server e o tempo tiver expirado, puff cai a conexão e vai pedir re-login e perdeu tudo.

    []s

    • Oi Pedro,
      É por isso que tem a parte do “cutucar” o servidor a cada 10 minutos nesse exemplo.
      Você também pode alterar para isso ser automático, não ficar apenas no lado cliente.
      Esse exemplo é só para dar uma idéia de como fazer! :)
      []‘s

Leave a Reply

Trackback URL | RSS Feed for This Entry

VideoPokiesOnline.com is the leading Pokies - Online Casino Guide in Australia. Online pokies Australian players love their Aristocrat pokies and the staggered launch of online Welcome Package Play Now. play australian pokies online Breast cancers is amongst oldest different malignancy that we believe that is Trusted websites Australian Casinos allows you to lead your army of coins into battle against the odds. Free Online Pokies at Top Rated Australian Online Casinos.
Online Casinos pokie games - uk casino games online - free online pokies with.
Slots and enjoy: ?one of a kind VIP program ? $500 Welcome Package ? Online Pokies Australia online casinos and land parlors. Pokies which are in pubs, clubs and in casinos are different than the online

Online Slots Wild Jack.