Em um aplicativo da web implementado em java usando JSP e Servlets; se eu armazenar informações na sessão do usuário, essas informações serão compartilhadas em todas as guias do mesmo navegador. Como diferenciar as sessões nas guias do navegador? Neste exemplo:
<%@page language="java"%>
<%
String user = request.getParameter("user");
user = (user == null ? (String)session.getAttribute("SESSIONS_USER") : user);
session.setAttribute("SESSIONS_USER",user);
%>
<html><head></head><body>
<%=user %>
<form method="post">
User:<input name="user" value="">
<input type="submit" value="send">
</form>
</body></html>
Copie esse código em uma página jsp ( testpage.jsp
), implante esse arquivo em um contexto existente de um aplicativo Web no servidor (eu uso o Apache Tomcat) e abra um navegador (FF, IE7 ou Opera) usando a URL correta ( localhost/context1/testpage.jsp
), digite seu nome na entrada e envie o formulário. Em seguida, abra uma nova guia no mesmo navegador e você poderá ver seu nome (obtido da sessão) na nova guia. Cuidado com o cache do navegador, às vezes parece que isso não acontece, mas está no cache, atualize a segunda guia.
Obrigado.
Respostas:
Você pode usar o HTML5 SessionStorage (window.sessionStorage). Você irá gerar um ID aleatório e salvar na sessão Armazenamento por guia do navegador. Em seguida, cada guia do navegador tem seu próprio ID.
fonte
Você deve perceber que as sessões do lado do servidor são um complemento artificial para o HTTP. Como o HTTP é sem estado, o servidor precisa reconhecer de alguma forma que uma solicitação pertence a um usuário específico que ele conhece e tem uma sessão. Existem 2 maneiras de fazer isso:
O que você está tentando fazer, afinal? Por que você deseja que as guias tenham sessões separadas? Talvez haja uma maneira de atingir seu objetivo sem usar sessões?
Editar: para teste, outras soluções podem ser encontradas (como executar várias instâncias do navegador em VMs separadas). Se um usuário precisar atuar em diferentes funções ao mesmo tempo, o conceito de "função" deve ser tratado no aplicativo para que um login possa ter várias funções. Você terá que decidir se isso, usando a reescrita de URL ou apenas vivendo com a situação atual é mais aceitável, porque simplesmente não é possível lidar com as guias do navegador separadamente com sessões baseadas em cookies.
fonte
A propriedade Javascript window.name é a única coisa que persiste na atividade da guia, mas pode permanecer independente (em vez do bloqueio de URL).
fonte
Você não deveria. Se você quiser fazer isso, precisará forçar o usuário a usar uma única instância do seu aplicativo, escrevendo URLs dinamicamente, use um id de sessionID (não o sessionid, não funcionará) e passá-lo em todos os URLs.
Não sei por que você precisa, mas, a menos que precise fazer um aplicativo totalmente inutilizável, não faça isso.
fonte
Eu vim com uma nova solução, que tem um pouco de sobrecarga, mas parece estar funcionando até agora como um protótipo. Uma suposição é que você esteja em um ambiente de sistema de honra para efetuar login, embora isso possa ser adaptado solicitando novamente uma senha sempre que você alternar as guias.
Use localStorage (ou equivalente) e o evento de armazenamento HTML5 para detectar quando uma nova guia do navegador mudou qual usuário está ativo. Quando isso acontecer, crie uma sobreposição fantasma com uma mensagem dizendo que você não pode usar a janela atual (ou desativar a janela temporariamente, talvez não seja tão visível assim.) Quando a janela recuperar o foco, envie um registro de solicitação AJAX o usuário de volta.
Uma ressalva a esta abordagem: você não pode ter chamadas AJAX normais (isto é, aquelas que dependem da sua sessão) acontecem em uma janela que não tem o foco (por exemplo, se você recebeu uma chamada após um atraso), a menos que você faz manualmente uma chamada de re-login do AJAX antes disso. Então, na verdade, tudo o que você precisa é fazer com que sua função AJAX verifique primeiro para garantir que localStorage.currently_logged_in_user_id === window.yourAppNameSpace.user_id e, se não, faça login primeiro através do AJAX.
Outra são as condições de corrida: se você pode alternar entre janelas rápido o suficiente para confundi-las, pode acabar com uma sequência relogin1-> relogin2-> ajax1-> ajax2, com o ajax1 sendo feito na sessão errada. Para contornar isso, envie solicitações AJAX de login para uma matriz e, em seguida, armazene e antes de emitir uma nova solicitação de login, aborte todas as solicitações atuais.
A última dica a ser observada é a atualização de janelas. Se alguém atualizar a janela enquanto você tiver uma solicitação de login AJAX ativa, mas não concluída, ela será atualizada no nome da pessoa errada. Nesse caso, você pode usar o evento beforeunload fora do padrão para avisar o usuário sobre a possível confusão e solicitar que ele clique em Cancelar, enquanto reemite uma solicitação de login do AJAX. Então, a única maneira de fazer isso é clicando em OK antes da conclusão da solicitação (ou pressionando acidentalmente a tecla Enter / barra de espaço, porque OK é - infelizmente para este caso - o padrão). Existem outras maneiras de lidar com esse caso, como detectar as teclas F5 e Ctrl + R / Alt + R, que funcionam na maioria dos casos, mas podem ser frustradas pela reconfiguração de atalhos de teclado do usuário ou uso alternativo do SO. No entanto, este é um caso de ponta na realidade, e os piores cenários nunca são tão ruins: em uma configuração do sistema de honra, você seria logado como a pessoa errada (mas você pode deixar óbvio que esse é o caso personalizando páginas com cores, estilos, nomes exibidos de forma destacada, etc.); em uma configuração de senha, o ônus recai sobre a última pessoa que digitou sua senha para ter desconectado ou compartilhado sua sessão ou, se essa pessoa é realmente o usuário atual, não há violação.
Mas, no final, você tem um aplicativo de um usuário por guia que (espero) apenas age como deveria, sem ter que necessariamente configurar perfis, usar o IE ou reescrever URLs. Certifique-se de tornar óbvio em cada guia que está logado nessa guia específica, embora ...
fonte
Tivemos esse problema e resolvemos com muita facilidade. Quero dizer fácil, porque não há programação envolvida. O que queríamos fazer era permitir que um usuário fizesse login em várias contas na mesma janela do navegador sem entrar em conflito com as sessões.
Portanto, a solução foram subdomínios aleatórios.
Por isso, pedimos ao administrador do sistema para configurar os certificados SSL para * .abc.com e abc.com. Com poucas alterações de código, toda vez que um usuário tenta fazer login, ele é logado em uma guia com um número aleatório de subdomínio. para que cada guia possa ter sua própria sessão independentemente. Também para evitar conflitos, desenvolvemos o número aleatório usando um hash ou md5 do ID do usuário.
fonte
Serei honesto aqui. . . tudo acima pode ou não ser verdade, mas tudo parece MUITO muito complicado, ou não aborda saber o guia está sendo lado do servidor utilizado.
Às vezes precisamos aplicar a navalha de Occam.
Aqui está a abordagem da Occam: (não, eu não sou Occam, ele morreu em 1347)
1) atribua um ID exclusivo do navegador à sua página em carregamento. . . se e somente se a janela ainda não tiver um ID (use um prefixo e uma detecção)
2) em todas as páginas que você possui (use um arquivo global ou algo assim), basta colocar o código no local para detectar o evento de foco e / ou o evento do mouseover. (Vou usar o jquery para esta parte, para facilitar a escrita do código)
3) em sua função de foco (e / ou mouseover), defina um cookie com o nome da janela.
4) leia esse valor do cookie do seu servidor quando precisar ler / gravar dados específicos da guia.
Lado do cliente:
lado do servidor (C # - para fins de exemplo)
Feito.
fonte
Você pode usar a reescrita de link para anexar um identificador exclusivo a todos os seus URLs ao iniciar em uma única página (por exemplo, index.html / jsp / o que for). O navegador usará os mesmos cookies para todas as suas guias, para que tudo que você coloca nos cookies não seja exclusivo.
fonte
Acho que o que você provavelmente quer é manter o estado de navegação nas guias e não criar especificamente uma única sessão por guia. É exatamente isso que a estrutura Seam alcança com o escopo / contexto da Conversa. A implementação deles baseia-se no fato de que um ID de conversa é propagado a cada solicitação e cria a noção de conversa no lado do servidor, que é algo que fica entre uma sessão e uma solicitação. Permite controle de fluxo de navegação e gerenciamento de estado.
Embora o objetivo principal seja o JSF, dê uma olhada e verifique se há algo em que você pode tirar algumas idéias: http://docs.jboss.org/seam/latest/reference/en-US/html_single/#d0e3620
fonte
Em javascript, como identificar exclusivamente uma janela do navegador de outra que esteja na mesma sessionId baseada em cookId
Essencialmente, use window.name. Se não estiver definido, configure-o para um valor exclusivo e use-o. Será diferente nas guias que pertencem à mesma sessão.
fonte
Outra abordagem que funciona é criar um ID de janela exclusivo e armazenar esse valor junto com o ID da sessão em uma tabela de banco de dados. O ID da janela que costumo usar é inteiro (agora). Esse valor é criado quando uma janela é aberta e atribuída novamente à mesma janela se a janela for atualizada, recarregada ou enviada a si mesma. Os valores da janela (entradas) são salvos na tabela local usando o link. Quando um valor é necessário, ele é obtido da tabela do banco de dados com base no link de id da janela / id da sessão. Embora essa abordagem exija um banco de dados local, é praticamente à prova de falhas. O uso de uma tabela de banco de dados foi fácil para mim, mas não vejo razão para que matrizes locais não funcionem tão bem.
fonte
Desenvolvi recentemente uma solução para esse problema usando cookies. Aqui está um link para minha solução. Também incluí o código de exemplo da solução usando o ASP.NET; você poderá adaptá-lo ao JSP ou Servelets, se necessário.
https://sites.google.com/site/sarittechworld/track-client-windows
fonte
O Spring Session suporta várias sessões no mesmo navegador Veja os exemplos e detalhes da implementação http://docs.spring.io/spring-session/docs/current/reference/html5/guides/users.html
fonte
Nota: A solução aqui precisa ser feita no estágio de design do aplicativo. Seria difícil projetar isso mais tarde.
Use um campo oculto para passar pelo identificador da sessão .
Para que isso funcione, cada página deve incluir um formulário:
Todas as ações do seu lado, incluindo a navegação, enviam o formulário de volta (configurando
action
conforme apropriado). Para solicitações "inseguras" , você pode incluir outro parâmetro, por exemplo, contendo um valor JSON dos dados a serem enviados:Como não existem cookies, cada guia será independente e não terá conhecimento de outras sessões no mesmo navegador.
Muitas vantagens, principalmente quando se trata de segurança:
Algumas desvantagens:
Mais informações aqui .
fonte
Eu resolvi isso da seguinte maneira:
aqui o código:
Espero te ajudar
fonte
Estive lendo este post porque pensei que queria fazer a mesma coisa. Eu tenho uma situação semelhante para um aplicativo em que estou trabalhando. E realmente é uma questão de testar mais do que praticidade.
Depois de ler essas respostas, especialmente a de Michael Borgwardt, percebi o fluxo de trabalho que precisa existir:
Isso resolverá o problema de o usuário ver os dados de "outro usuário" em sua sessão. Eles realmente não estão vendo os dados de "outro usuário" na sessão, estão realmente vendo os dados da única sessão que eles abriram. Claramente, isso causa alguns dados interessantes, pois algumas operações substituem alguns dados da sessão e não outros, para que você tenha uma combinação de dados nessa única sessão.
Agora, para resolver o problema de teste. A única abordagem viável seria aproveitar as diretivas de pré-processador para determinar se as sessões sem cookies devem ser usadas. Veja, construindo uma configuração específica para um ambiente específico, sou capaz de fazer algumas suposições sobre o ambiente e para que é usado. Isso me permitiria tecnicamente ter dois usuários conectados ao mesmo tempo, e o testador poderia testar vários cenários da mesma sessão do navegador sem precisar sair de nenhuma dessas sessões do servidor.
No entanto, essa abordagem tem algumas advertências sérias. Não menos importante é o fato de que o testador está testando não é o que será executado na produção.
Então, acho que tenho que dizer que, no final das contas, é uma má ideia.
fonte
Armazenando o timeStamp em window.sessionStorage, se ainda não estiver definido. Isso fornecerá um valor exclusivo para cada guia (mesmo que os URLs sejam iguais)
http://www.javascriptkit.com/javatutors/domstorage.shtml
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage
Espero que isto ajude.
fonte
A maneira mais direta de diferenciar sessões nas guias do navegador é proibir que seu domínio específico defina cookies. Dessa forma, você pode ter sessões separadas de guias separadas. Digamos que você não permita cookies deste domínio: www.xyz.com. Você abre a guia 1, efetua login e começa a navegar. Em seguida, você abre a guia 2 e pode efetuar login como um mesmo usuário ou outro; de qualquer maneira, você terá uma sessão separada da guia 1. E assim por diante.
Mas é claro que isso é possível quando você tem controle sobre o lado do cliente. Caso contrário, as soluções prescritas pelas pessoas aqui devem ser aplicadas.
fonte
você precisará fazer
1- armazene um cookie para a lista de contas
2- armazenar opcionalmente um cookie como padrão
3- armazene para cada conta com seu índice como acc1, acc2
4- coloque no URL algo que represente o índice de contas e, caso contrário, você selecionará o padrão como google mail domain.com/0/some-url >> 0 aqui representa o índice de conta e talvez seja necessário saber como use urlwrite
5- ao selecionar um cookie, selecione-o de acordo com o caminho da URL que representa o índice da conta
Saudações
fonte
Eu vejo muitas implementações que têm alterações no lado do cliente para manipular cookies de identificação de sessão. Mas, em geral, os cookies de identificação de sessão devem ser HttpOnly, portanto, o java-script não pode acessar, caso contrário, pode levar ao Session Hijack através do XSS
fonte
Se é porque cada guia estará executando um fluxo diferente no seu aplicativo e a mistura dos dois fluxos causar problemas, é melhor "Regionalizar" seus objetos de sessão, para que cada fluxo use uma região diferente da sessão
Essa região pode ser implementada simplesmente como tendo prefixos diferentes para cada fluxo, ou o objeto de sessão conterá vários mapas (um para cada fluxo) e você os usará em vez de atributos de sessão, o melhor seria estender sua classe de sessão e use-o.
fonte