JSP 및 서블릿을 사용하여 Java로 구현 된 웹 애플리케이션에서; 사용자 세션에 정보를 저장하면이 정보는 동일한 브라우저의 모든 탭에서 공유됩니다. 브라우저 탭에서 세션을 달리하는 방법은 무엇입니까? 이 예에서 :
<%@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>
이 코드를 jsp 페이지 ( testpage.jsp
) 에 복사 하고 서버에서 웹 응용 프로그램의 기존 컨텍스트 에이 파일을 배포 한 다음 (Apache Tomcat 사용) 올바른 URL ( localhost/context1/testpage.jsp
)을 사용하여 브라우저 (FF, IE7 또는 Opera)를 열고 입력에 귀하의 이름과 양식을 제출하십시오. 그런 다음 동일한 브라우저에서 새 탭을 연 다음 새 탭에서 이름을 볼 수 있습니다 (세션에서 가져옴). 브라우저 캐시에주의하십시오. 때로는 발생하지 않는 것처럼 보이지만 캐시에 있으면 두 번째 탭을 새로 고칩니다.
감사.
답변
HTML5 SessionStorage (window.sessionStorage)를 사용할 수 있습니다. 임의의 ID를 생성하고 브라우저 탭마다 세션 저장소에 저장합니다. 그런 다음 각 브라우저 탭에는 고유 한 ID가 있습니다.
sessionStorage를 사용하여 저장된 데이터는 두 탭에 모두 동일한 도메인 출처의 웹 페이지가 포함되어 있어도 브라우저 탭간에 유지되지 않습니다. 즉, sessionStorage 내부의 데이터는 호출 페이지의 도메인 및 디렉토리뿐만 아니라 페이지가 포함 된 브라우저 탭으로 제한됩니다. 세션 쿠키와는 대조적으로, 데이터를 탭에서 탭으로 유지합니다.
답변
서버 측 세션은 HTTP에 대한 인공 추가 기능이라는 것을 알아야합니다. HTTP는 상태 비 저장이므로 서버는 요청이 알고 있고 세션을 가지고있는 특정 사용자의 요청임을 인식해야합니다. 이를 수행하는 두 가지 방법이 있습니다.
- 쿠키. 더 깨끗하고 인기있는 방법이지만 한 명의 사용자가 모든 브라우저 탭과 창을 세션을 공유한다는 것을 의미합니다 .IMO 이것은 실제로 바람직하며 새 탭마다 로그인 한 사이트에서 매우 화가 나기 때문에 탭을 매우 집중적으로 사용
- URL 재 작성 사이트의 모든 URL에는 세션 ID가 추가됩니다. 이것은 더 많은 작업이지만 (사이트 내부 링크가있는 모든 곳에서 무언가를해야합니다), 링크를 통해 열린 탭은 여전히 세션을 공유하지만 다른 탭에서 별도의 세션을 가질 수 있습니다. 또한 사용자가 사이트에 올 때 항상 로그인해야 함을 의미합니다.
어쨌든 무엇을하려고합니까? 왜 탭이 별도의 세션을 갖기를 원하십니까? 세션을 전혀 사용하지 않고 목표를 달성 할 수있는 방법이 있습니까?
편집 :
테스트를 위해 다른 솔루션 (예 : 별도의 VM에서 여러 브라우저 인스턴스 실행)을 찾을 수 있습니다. 한 명의 사용자가 동시에 다른 역할을 수행해야하는 경우 하나의 로그인이 여러 역할을 가질 수 있도록 앱에서 “역할”개념을 처리해야합니다. 쿠키 기반 세션을 사용하여 브라우저 탭을 개별적으로 처리 할 수 없기 때문에 URL 재 작성을 사용하거나 현재 상황에 따라 생활하는 것이 더 적합한 지 여부를 결정해야합니다.
답변
window.name Javascript 속성은 탭 활동 전체에서 유지되지만 URL guff 대신 독립적으로 유지 될 수있는 유일한 것입니다.
답변
해서는 안됩니다. 이러한 작업을 수행하려면 즉시 URL을 작성하여 사용자가 응용 프로그램의 단일 인스턴스를 사용하도록 강제해야합니다 (세션 ID가 아닌) 세션 ID를 동일하게 사용하고 모든 URL에 전달하십시오.
왜 필요한지 모르겠지만 완전히 사용할 수없는 응용 프로그램을 만들지 않는 한 그렇게하지 마십시오.
답변
약간의 오버 헤드가 있지만 프로토 타입으로 작동하는 것처럼 보이는 새로운 솔루션을 생각해 냈습니다. 탭을 전환 할 때마다 비밀번호를 다시 요청하면이 설정을 적용 할 수 있지만 한 가지 가정은 사용자가 로그인하기 위해 명예 시스템 환경에 있다는 것입니다.
localStorage (또는 이와 동등한) 및 HTML5 스토리지 이벤트를 사용하여 새 브라우저 탭이 활성화 된 사용자를 전환 한시기를 감지하십시오. 이 경우 현재 창을 사용할 수 없다는 메시지와 함께 고스트 오버레이를 작성하십시오 (또는 그렇지 않으면 창을 일시적으로 사용하지 않도록 설정하는 것이 바람직하지 않을 수 있습니다). 창에 초점이 다시 오면 AJAX 요청 로깅을 보내십시오. 다시 사용자.
이 접근 방식에 대한 한 가지 경고 : 일반적인 AJAX 호출 (예 : 세션에 의존하는 호출)은 포커스가없는 창에서 발생할 수 없습니다 (예 : 지연 후 호출이 발생한 경우). 그 전에 AJAX 재 로그인 호출을 수동으로 수행하십시오. 따라서 실제로 필요한 것은 AJAX 기능을 먼저 확인하여 localStorage.currently_logged_in_user_id === window.yourAppNameSpace.user_id를 확인하고 그렇지 않은 경우 AJAX를 통해 먼저 로그인하십시오.
다른 하나는 경쟁 조건입니다. 혼동하기에 충분히 빠른 속도로 창을 전환 할 수 있으면 relogin1-> relogin2-> ajax1-> ajax2 시퀀스가 발생하고 ajax1이 잘못된 세션에서 생성 될 수 있습니다. 이 문제를 해결하려면 로그인 AJAX 요청을 어레이로 푸시 한 다음 저장시 새 로그인 요청을 발행하기 전에 모든 현재 요청을 중단하십시오.
마지막으로 살펴 봐야 할 것은 창 새로 고침입니다. AJAX 로그인 요청이 활성화되었지만 완료되지 않은 상태에서 누군가가 창을 새로 고치면 잘못된 사람의 이름으로 새로 고쳐집니다. 이 경우 비표준 beforeunload 이벤트를 사용하여 잠재적 믹스 업에 대해 사용자에게 경고하고 AJAX 로그인 요청을 재발행하는 동안 취소를 클릭하도록 요청할 수 있습니다. 그런 다음 요청을 완료하기 전에 확인을 클릭하거나 실수로 Enter / Spacebar를 누르는 것이 유감입니다. 불행히도이 경우 기본값은 기본값입니다.)이 경우를 처리하는 다른 방법이 있습니다. F5 및 Ctrl + R / Alt + R 누름 감지-대부분의 경우 작동하지만 사용자 키보드 단축키 재구성 또는 대체 OS 사용으로 인해 방해받을 수 있습니다. 그러나 이것은 실제로 약간의 경우입니다. 최악의 시나리오는 결코 그렇게 나쁘지 않습니다. 명예 시스템 구성에서는 잘못된 사람으로 로그인했을 것입니다 (그러나 색상, 스타일, 눈에 잘 띄게 표시되는 이름, 기타.); 비밀번호 구성에서, onus는 마지막으로 로그 아웃하거나 세션을 공유하기 위해 비밀번호를 입력 한 사람에게 있거나이 사람이 실제로 현재 사용자 인 경우 위반이 없습니다.
그러나 결국에는 프로파일을 설정하거나 IE를 사용하거나 URL을 다시 작성할 필요없이 탭당 하나의 사용자 당 응용 프로그램이 있어야합니다. 그래도 특정 탭에 로그인 한 각 탭에서 분명히해야합니다.
답변
우리는이 문제를 겪었고 매우 쉽게 해결했습니다. 프로그래밍이 필요하지 않기 때문에 쉽게 의미합니다. 우리가하고 싶었던 것은 사용자가 세션을 충돌시키지 않고 동일한 브라우저 창에서 여러 계정에 로그인하도록하는 것입니다.
따라서 솔루션은 임의의 하위 도메인이었습니다.
23423.abc.com
242234.abc.com
235643.abc.com
따라서 시스템 관리자에게 abc.com 대신 * .abc.com에 대한 SSL 인증서를 구성하도록 요청한 다음 사용자가 로그인을 시도 할 때마다 코드 변경이 거의없이 임의의 하위 도메인 번호가있는 탭에 로그인됩니다. 각 탭은 독립적으로 자체 세션을 가질 수 있습니다. 또한 충돌을 피하기 위해 사용자 ID의 해시 또는 md5를 사용하여 난수를 개발했습니다.
답변
나는 정직 할 것이다. . . 위의 모든 것이 사실 일 수도 있고 아닐 수도 있지만 , 너무 복잡해 보이 거나 서버 측에서 어떤 탭이 사용되고 있는지 알지 못합니다.
때때로 우리는 Occam의 면도기를 적용해야합니다.
Occam의 접근 방식은 다음과 같습니다. (아니, Occam은 아닙니다. 그는 1347 년에 사망했습니다)
1)로드시 페이지에 브라우저 고유 ID를 할당하십시오. . . 창에 아직 ID가없는 경우에만 (접두사와 감지 기능을 사용하십시오)
2) 모든 페이지에서 (글로벌 파일 또는 무언가 사용) 단순히 포커스 이벤트 및 / 또는 마우스 오버 이벤트를 감지하기 위해 코드를 배치하십시오. (코드 작성을 쉽게하기 위해이 부분에 jquery를 사용합니다)
3) 포커스 (및 / 또는 마우스 오버) 기능에서 window.name으로 쿠키를 설정하십시오.
4) 탭 특정 데이터를 읽거나 써야 할 때 서버 측에서 쿠키 값을 읽으십시오.
고객 입장에서:
//Events
$(window).ready(function() {generateWindowID()});
$(window).focus(function() {setAppId()});
$(window).mouseover(function() {setAppId()});
function generateWindowID()
{
//first see if the name is already set, if not, set it.
if (se_appframe().name.indexOf("SEAppId") == -1){
"window.name = 'SEAppId' + (new Date()).getTime()
}
setAppId()
}
function setAppId()
{
//generate the cookie
strCookie = 'seAppId=' + se_appframe().name + ';';
strCookie += ' path=/';
if (window.location.protocol.toLowerCase() == 'https:'){
strCookie += ' secure;';
}
document.cookie = strCookie;
}
서버 측 (C #-예를 들어 목적)
//variable name
string varname = "";
HttpCookie aCookie = Request.Cookies["seAppId"];
if(aCookie != null) {
varname = Request.Cookies["seAppId"].Value + "_";
}
varname += "_mySessionVariable";
//write session data
Session[varname] = "ABC123";
//readsession data
String myVariable = Session[varname];
끝난.