|
=============================== login.jsp ============================
<%
/*
* 로그인 페이지, 로그인전 현재 로그인된 이용자수를 출력한다.
*/
%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"%>
<%@ page import="test.LoginManager"%>
<%!
//싱글톤 패턴을 사용하였기 때문에 생생되어있는 인스턴스를 얻어온다.
LoginManager loginManager = LoginManager.getInstance();
%>
<%
//login_try에서 로그인을 하지 않을경우 세션에 남아있는 userId를 제거한다.
session.removeAttribute("userId");
%>
<html>
<head>
<title>로그인 중복방지 Test</title>
</head>
<body>
<h3 align="center">현재 접속자 수 : <%=loginManager.getUserCount() %>명</h3>
<form action="login_try.jsp" name="login">
<div align="center">
아이디 : <input type="text" name="userId"><br>
비밀번호 : <input type="passward" name="userPw"><br>
<input type="submit" value="로그인">
</div>
</form>
</body>
</html>
============================= login_try.jsp ============================
<%
/*
* 로그인 시도페이지, id, pw유무를 체크하고, 올바르다면
* 이미 접속한 아이디인지 체크한다. 이미 접속한 아이디라면
* 기존 접속을 유지할것인지, 기존접속을 kill시키고 로그인할것인지를
* 확인한다.
*/
%>
<%@ page language="java" contentType="text/html; charset=EUC-KR" %>
<%@ page import="test.LoginManager"%>
<%!
//싱글톤 패턴을 사용하였기 때문에 생생되어있는 인스턴스를 얻어온다.
LoginManager loginManager = LoginManager.getInstance();
%>
<html>
<head>
<title>로그인 중복방지 Test</title>
</head>
<body align="center" valign="center">
<%
String userId = request.getParameter("userId");
String userPw = request.getParameter("userPw");
//아이디 패스워드 체크
if(loginManager.isValid(userId, userPw)){
//접속자 아이디를 세션에 담는다.
session.setAttribute("userId", userId);
//이미 접속한 아이디인지 체크한다.
//out.println(userId);
//out.println(loginManager.isUsing(userId));
loginManager.printloginUsers();
if(loginManager.isUsing(userId)){
%>
이미 접속중입니다. 기존의 접속을 종료하시겠습니까?<P>
<a href="disconnect.jsp">예 </a>
<a href="login.jsp">아니오</a>
<%
}else{
loginManager.setSession(session, userId);
response.sendRedirect("login_ok.jsp");
}
%>
<%
}else{
%>
<script>
alert("로그인후 이용해 주세요.");
location.href = "login.jsp";
</script>
<%
}
%>
</body>
</html>
========================== disconnect.jsp ============================
<%
/*
* login_try.jsp에서 로그인 중복시 무시하고 로그인할경우 호출.
* 기존의 session을 끊고 hashTable에 저장후 login_ok.jsp를 호출.
*/
%>
<%@ page language="java" contentType="text/html; charset=EUC-KR" %>
<%@ page import="test.LoginManager"%>
<%!
//싱글톤 패턴을 사용하였기 때문에 생생되어있는 인스턴스를 얻어온다.
LoginManager loginManager = LoginManager.getInstance();
%>
<html>
<head>
<title>로그인 중복방지 Test</title>
</head>
<body>
<%
String userId = (String)session.getAttribute("userId");
if(userId != null){
//기존의 접속(세션)을 끊는다.
loginManager.removeSession(userId);
//새로운 세션을 등록한다. setSession함수를 수행하면 valueBound()함수가 호출된다.
loginManager.setSession(session, userId);
response.sendRedirect("login_ok.jsp");
}
%>
</body>
</html>
============================= login_ok.jsp ============================
<%
/*
* 정상적으로 로그인되었을경우 호출
* 접속자 아이디를 보여주고 현재 접속중인 모든 사용자를 뿌려준다.
*/
%>
<%@ page language="java" contentType="text/html; charset=EUC-KR" %>
<%@ page import="java.util.*, test.LoginManager"%>
<%!
//싱글톤 패턴을 사용하였기 때문에 생생되어있는 인스턴스를 얻어온다.
LoginManager loginManager = LoginManager.getInstance();
%>
<html>
<head>
<title>로그인 중복방지 Test</title>
</head>
<body align="center" valign="center">
<%
//jsp내장객체 session을 이용하여 접속자 아이디를 얻어온다.
String userId = (String)session.getAttribute("userId");
if(userId != null){
%>
<%=userId%>님 환영합니다.
<a href="logout.jsp">로그아웃</a>
<p>
현재 접속자 : <br>
<%
Collection collection = loginManager.getUsers();
Iterator iterator = collection.iterator();
int i=0;
while(iterator.hasNext()){
out.print((++i)+". "+iterator.next()+"<br>");
}
}else{
%>
<script>
alert("로그인후 이용해 주세요.");
location.href = "login.jsp";
</script>
<%
}
%>
</body>
</html>
============================= logout.jsp ==============================
<%
/*
* 로그아웃을 클릭했을때 호출된다.
*/
%>
<%@ page language="java" contentType="text/html; charset=EUC-KR" %>
<%
//session을 확~~~끊어 버린다. 이시점에 LoginManager의 valueUnbound()가 호출된다.
session.invalidate();
response.sendRedirect("login.jsp");
%>
지금까지 중복로그인 체크를 막기위한 테스트를 해 보았다.
처음 강좌에서 얘기했던 윈도우 닫기버튼,
윈도우 닫기 단축키인 Alt+F4, Ctrl+E를 수행했을때 세션을 끊는방법을
알아보겠다. 우리가 아래 예제를 수행했던 이유를 먼저 알아보자.
특정 사용자가 로그인을 시도한다고 생각해보자.
일반 웹사이트에서는 로그인을하고 다른쪽에서
로그인을 시도할경우 아무런 대책없이 로그인을 허용하였다.
우리가 많이 사용하는 메신저의 예를 들어보자.
메신저의 경우 로그인을 했을시 이미 접속중이라는 메시지가 뜨게된다.
만약 위와같은 메시지가 수시로 뜬다면
자신의 id가 누군가가 도용해서 사용중이라는 사실을 알수있을것이다...
그런 느낌이 온다면 우리는 id, password를 변경하여 정보누출을
어느정도 막을수 있을것이다.
그리고 또하나 자신의 계정으로 접속중에 제 3자의 누군가가 로그인을 했다면
누군가가 다른곳에서 접속중이라는 메시지를 뿌려줄수 있다면 훨씬 더 좋을
것이다.
우리가 만든 예제에서는 몇가지 문제점이 있다.
위기능을 사용하기 위해서는 로그인시 누군가가 자신의 id로
이미 로그인 중인지를 알아내는것이 중요하다.
그리고 이미 로그인된것이 확인 되었다면 자신이 로그인하기를 원한다면
이미 로그인한 세션을 끊고 자신의 세션을 등록해야한다..
그러기 위해서 우리는 해시테이블을 사용하였으며..
기존의 세션을 끊기위해서 세션 오브젝트를 직접 담았다.
문제점은 누군가가 자신의 id로 이미 로그인중인지 알아내는것이다.
우리가 로그인을 하고 무조건 로그아웃버튼을 클릭했다면 그당시 세션을 끊어
다른곳에서의 로그인을 바로 허용하면 되지만 닫기버튼을 누를때나
Alt+F4, Ctrl+E를 누를때 이벤트를 잡지못하면 안된다는것이다.
그렇지 못하면 그 세션은 서버의 메모리에 계속 살아서 세션이 타임아웃되기
까지는 계속 살아있을것이다.(이때는 HttpSessionBindingListener의 valueUnbound함수가 서블릿 컨테이너에서 호출한다.)
정상적으로 로그아웃버튼을 누르고 브라우저를 닫는사람이 어디있겠는가?
대게의 사용자들은 로그아웃을 하지 않고 바로 닫아버릴것이다.
여기서 위의 방법으로 닫았을때 이벤트를 잡을수 있는 방법을 설명하겠다.
예제는 간단하다.
============================== main.jsp ==============================
<frameset rows="0,*" border="0">
<frame name="duplChkFrame" scrolling=no frameborder=0 marginwidth="0" marginheight="0" src='frame.html' noresize>
<frame name="topFrame" scrolling="no" frameborder=0 marginwidth="0" marginheight="0" target="mainFrame" src="mainFrame.jsp" noresize>
</frameset>
============================== frame.html' ============================
<html>
<head>
<script>
/**
* logout()
* 작 성 자 : 권홍재
* 작 성 일 : 2006-12-18
* 개 요 : 브라우저가 닫길시 호출
* return값 : void
*/
function logout(){
location.href = 'logout.jsp';
}
</script>
</head>
<body OnUnload="logout()">
</body>
</html>
위처럼 onUnLoad이벤트를 사용하면 된다.
프레임으로 나눈 이유는 브라우저가 하나의 프레임만으로 되어있다면..
페이지 이동시마다 onUnLoad이벤트가 발생한다는것이다..
곧 페이지가 이동시마다 로그아웃이 발생한다는뜻이며
고로 세션이 끊겨서 페이지를 이동할수 없다는 말이 된다.
이를 방지하기 위해서 프레임으로 나누어서 메인 프레임에는
일반적인 페이지를 호출을 하고 로그아웃 페이지를 호출하는부분은
페이지가 변경되지 않는 frame.html에서 로그아웃 처리를 하는것이다.
페이지가 닫길때 frame.html에서 onUnLoad이벤트가 발생하여
logout.jsp를 호출하는것이다.
참... 그리고 한가지 새로고침버튼이나 F5번버튼 마우스 오른쪽 버튼을
클릭하고 새로고침을 할경우는 어쩔수 없다는 것이다..
페이지를 다시 부르는것이기때문에 페이지를 부르기전 기존페이지가
죽기전에 onUnload이벤트가 발생한다는 것이다. 이를 해결하기 위해서는
마우스 오른쪽버튼 상단의 메누 보이지 않기, 키업이벤트에서 F5번키를
막는수밖에는 없다.^^;
이것으로 중복로그인체크 강좌를 마치겠다...^^*
'JAVA' 카테고리의 다른 글
java unsigned (2) | 2012.02.09 |
---|---|
세션이 생성되고 관리되는 과정 (3) | 2011.08.12 |
java 형변환 모음 (1) | 2011.04.06 |
자바 iBATIS 결과를 XML 리턴받기 : xmlResultName , java , xml (1) | 2011.04.06 |
태그 제거 정규식 (2) | 2011.03.16 |