Pergunta

Meu requisito é notificar o usuário com um pop -up dizendo que a sessão do usuário está prestes a passar em x segundos, caso o usuário não execute nenhuma atividade na página da web.

Além disso, é necessário diminuir o valor x segundos dinamicamente no pop -up.

O ambiente que eu uso é Java EE.

Foi útil?

Solução

Fazer uso de HttpSession#getMaxInactiveInterval() e setTimeout(). Não há necessidade de Ajax nesse objetivo específico, a menos que você queira adiar o tempo limite em todas as atividades do cliente (pesquisa).

Exemplo básico:

<script>
    var secondsBeforeExpire = ${pageContext.session.maxInactiveInterval};
    var timeToDecide = 15; // Give client 15 seconds to choose.
    setTimeout(function() {
        alert('Your session is about to timeout in ' + timeToDecide + ' seconds!')
    }, (secondsBeforeExpire - timeToDecide) * 1000);
</script>

Para diminuir o tempo dentro da mensagem magicamente, então em vez do básico alert() você precisará de uma sobreposição com uma div, em que você tem controle sobre o conteúdo através da árvore html dom e use outro setTimeout() em 1 segundo para alterar o texto dinamicamente.

Observe que este script deve ser servido pelo JspServlet Para fazer o EL funcionar. Assim, você precisa colocar o script no HTML <head> da página JSP, ou se você realmente deseja ter todo o JS em um separado *.js arquivo, então você precisa deixar o JspServlet lidar com qualquer *.js solicitações também.

Outras dicas

Eu não acho que o Java/Java EE será realmente útil aqui, pois isso precisa ser tratado no lado do cliente (ou seja, usando o JavaScript). Uma solução em que posso pensar seria definir um tipo de temporizador que notificaria o usuário alguns minutos antes do tempo limite do servidor.

Enquanto pesquisava no Google sobre isso, encontrei o Eric Pascarello Atualize a sessão do usuário com Ajax Postagem do blog (e a versão recarregada Atualizando a sessão do usuário com Ajax - Rodada 2) que descreve com precisão essa solução (e use um XMLHttpRequest para atualizar a sessão). Seu script de gerenciamento de sessão do Ajax está disponível aqui.

Pode ser simples que o Logout automático de servlet, mvc ou mola de segurança não seja possível sem a lógica lateral perfeita do cliente.
Considerando que a aplicação terá o mesmo tipo de solicitação

  • Ajax e
  • envio de formulário/recarga da página

O logout automático precisa de lógica muito calculada. Apresentando minha implementação de funcionalidade autóloga com seguintes

Vantagens.


1. Nenhuma chamada/solicitação extra é usada para conseguir isso. Considerando o impacto do desempenho se mais de 10 mil usuários ativos e chamadas extras para obter logout automático.
2. Configuração de uma linha usando tag.
3. Funciona perfeitamente, mesmo se o usuário abrir várias guias ou várias janelas.
4. Ele sugere você antes de 30 segundos de invalidação da sessão; portanto, se você preencheu o formulário e não foi enviado, poderá manter a sessão viva (estender a sessão por um clique). Portanto, o usuário menos propenso a perder dados não salvos.

Uso


1. Inclua o script de logout automático nas páginas JSP necessárias, conforme fornecido abaixo.

    ....
    </body>
    <jsp:include page="../template/autologout-script.jsp"></jsp:include>
</html>

2. Crie uma página JSP, Autologout-Script.jsp e adicione o código abaixo.Nota: Nenhuma edição/configuração é necessária

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<script>
$(document).ready(function()
{
    var timeOutTimeInSeconds = ${ timeOutTimeInSeconds }; 
    var showTimerTimeInSeconds= ${ showTimerTimeInSeconds };

    var sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
    var timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
    var badgeTimerId;
    window.localStorage.setItem("AjaxRequestFired", new Date());

    function redirectToLoginPage(){
        //location.href =  '<c:url value="/" />'+'${loginPageUrl}';
        window.location.reload();
    }

    $(document).ajaxComplete(function () {
        resetTimer();
    });

    $(window).bind('storage', function (e) {
         if(e.originalEvent.key == "AjaxRequestFired"){
             console.log("Request sent from another tab, hence resetting timer")
             resetTimer();
         }
    });

    function resetTimer()
    {
        showTimerTimeInSeconds= ${ showTimerTimeInSeconds };

        console.log("timeOutTimeInSeconds : "+timeOutTimeInSeconds)
        window.localStorage.setItem("AjaxRequestFired", new Date());

        window.clearInterval(sessionCheckIntervalId);
        sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);

        window.clearInterval(timerDisplayIntervalId);
        timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);

        hideTimer();
    }

    function showTimer()
    {
        $('#sessionTimeRemaining').show();
        $('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
        window.clearInterval(timerDisplayIntervalId);
        badgeTimerId = setInterval(function(){
            $('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
        }, 1000);
    }

    function hideTimer()
    {
        window.clearInterval(badgeTimerId);
        $('#sessionTimeRemaining').hide();
    }
});
</script>

3. Configurar atributos da sessão para definir a configuração do tempo limiteNota: Configure isso após a criação da sessão. Você pode implementar o método HTTPSessionListener SessionCreated e definir a seguinte configuração conforme sua exigência.

session.setMaxInactiveInterval(300);

session.setAttribute("timeOutTimeInSeconds", 300);
session.setAttribute("showTimerTimeInSeconds", 30);

4. Adicione abaixo HTML para exibir timer.
NOTA: Ele pode ser movido para a página do modelo-script automaticamente se você for bom no CSS. Portanto, você pode evitar adicionar isso em todas as páginas.
Inclua Bootstrap ou adicione seu CSS personalizado.

<span class="badge badge-primary" title="click to keep session alive" id="sessionTimeRemaining" 
    onclick="ajaxSessionRefresh()" style="display:none;">
    <i class="badge badge-danger" id="sessionTimeRemainingBadge" style="float:left">30</i>
     &nbsp; 
     <small>Refresh</small>
     <i class="glyphicon glyphicon-refresh"></i>
</span>

enter image description here

Isso se trata de uma simples implementação de logout automática. Você pode baixar o exemplo de funcionamento do meu repositório GitHub
Autólogo usando um exemplo simples de servlet
Autólogo usando o exemplo de configuração de java de segurança da primavera
Autólogo usando o exemplo de configuração XML de segurança da primavera

Lógica explicou


Caso 1: no carregamento da página
Aqui, a lógica é simples, na página Carregar definir o timer das equas de intervalo para maxinactiveInterval. Após o tempo limite, redirecionar para a página de login.
Caso 2: Mantenha as chamadas do Ajax do rastreamento
Agora, considerando solicitações do AJAX, você pode usar .ajaxstart () ou .ajaxcomplete () retornos de chamada do jQuery para que, se alguma solicitação AJAX for disparada, você possa redefinir o intervalo.
Caso 3: Rastreando a atividade multi -guia/janela
A comunicação entre elegância é feita para sincronizar o estado de cada guia. Utilizou o evento LocalSorage on Change.

Limitações/melhorias necessárias
1. Se a sessão máxima permitida for uma, se a sessão for retirada de outro sistema, a solicitação AJAX falhará. Ele precisa ser tratado para redirecionar para a página de login.
2. Use Ajaxstart () em vez de AjaxComplete () para ter uma sincronização exata dos valores de IdleTime entre o servidor e o navegador.

Requisitos
1. JQuery

Alternativas à implementação atual em comparação


1. Definindo o cabeçalho da atualização Na resposta HTTP. (Não funciona para solicitações de Ajax)

response.setHeader("Refresh", "60; URL=login.jsp");
  1. Definir tag meta refresh em html (Não funciona para solicitações de Ajax)
<meta http-equiv="refresh" content="60; url=login.jsp">
  1. Configurando o verificador de atividadesMantém a sessão viva pela solicitação repetida do Ajax. Rastreia o tempo ocioso e faz solicitação de logout após o tempo limite.
    Sem dúvida, é bom com lógica simples. Mas eu quero apenas pintar minhas observações.
    • Impacto de desempenho Se 2 solicitações forem feitas por minuto para manter a sessão viva e 50 mil usuários ativos. 100k solicitações por minuto.
    • Comunicação Intertab Se duas guias estiverem abertas, uma guia está recebendo atividade, mas outra guia não está recebendo atividade, essa guia dispara a solicitação de logout e invalida sessão, mesmo que a atividade esteja presente em outra guia. (Mas pode ser tratado)
    • Abordagem de logout de força É um cliente dominado pelo servidor para invalidar sessão.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top