ExtJS 4: Gerenciamento de Sessão: Session Timeout
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:
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 11: maxInactive – 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!










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
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