/*
* 로그인 중복체크
* 이미 로그인한 사용자가 있을경우 기존의 사용자 세션을 종료후 자신이 로그인.
* 해시테이블에 세션과 접속자 아이디를 저장해 둔다.
* 세션 Object를 저장하는 이유는 동일한 아이디로 재접속 했을경우
* 아이디로 세션Object를 찾아내어 기존의 접속을 끊기위해서다.(invalidate)
* 거의 대부분의 웹사이트를 보면 브라우저를 열고 로그인후
* 또다시 다른브라우저를 열고 로그인을 하면 로그인이 되는것을 확인할 수 있다.
* 이는 즉... 여러곳에서 동일한 아이디로 접속을 할수있다는 것이다.
* 이와 반대로 메신저같은경우는 이미 로그인이 되어있을시 다른곳에서
* 로그인을 하면 접속을 끊을지를 물어보는 기능도 확인할 수 있는데. 이를 웹사이트에서도 구현하는 것이다.
*/
servlet을 이용함
============== WEB-INF\src\test\LoginManager.java ===============
package test;
import java.util.*;
import javax.servlet.http.*;
/*
* session이 끊어졌을때를 처리하기 위해 사용
* static메소드에서는 static만사용 하므로static으로 선언한다.
*/
public class LoginManager implements HttpSessionBindingListener{
private static LoginManager loginManager = null;
//로그인한 접속자를 담기위한 해시테이블
private static Hashtable loginUsers = new Hashtable();
/*
* 싱글톤 패턴 사용
*/
public static synchronized LoginManager getInstance(){
if(loginManager == null){
loginManager = new LoginManager();
}
return loginManager;
}
/*
* 이 메소드는 세션이 연결되을때 호출된다.(session.setAttribute("login", this))
* Hashtable에 세션과 접속자 아이디를 저장한다.
*/
public void valueBound(HttpSessionBindingEvent event) {
//session값을 put한다.
loginUsers.put(event.getSession(), event.getName());
System.out.println(event.getName() + "님이 로그인 하셨습니다.");
System.out.println("현재 접속자 수 : " + getUserCount());
}
/*
* 이 메소드는 세션이 끊겼을때 호출된다.(invalidate)
* Hashtable에 저장된 로그인한 정보를 제거해 준다.
*/
public void valueUnbound(HttpSessionBindingEvent event) {
//session값을 찾아서 없애준다.
loginUsers.remove(event.getSession());
System.out.println(" " + event.getName() + "님이 로그아웃 하셨습니다.");
System.out.println("현재 접속자 수 : " + getUserCount());
}
/*
* 입력받은 아이디를 해시테이블에서 삭제.
* @param userID 사용자 아이디
* @return void
*/
public void removeSession(String userId){
Enumeration e = loginUsers.keys();
HttpSession session = null;
while(e.hasMoreElements()){
session = (HttpSession)e.nextElement();
if(loginUsers.get(session).equals(userId)){
//세션이 invalidate될때 HttpSessionBindingListener를
//구현하는 클레스의 valueUnbound()함수가 호출된다.
session.invalidate();
}
}
}
/*
* 사용자가 입력한 ID, PW가 맞는지 확인하는 메소드
* @param userID 사용자 아이디
* @param userPW 사용자 패스워드
* @return boolean ID/PW가 일치하는 지 여부
*/
public boolean isValid(String userId, String userPw){
/*
* 이부분에 Database 로직이 들어간다.
*/
return true;
}
/*
* 해당 아이디의 동시 사용을 막기위해서
* 이미 사용중인 아이디인지를 확인한다.
* @param userID 사용자 아이디
* @return boolean 이미 사용 중인 경우 true, 사용중이 아니면 false
*/
public boolean isUsing(String userID){
return loginUsers.containsValue(userID);
}
/*
* 로그인을 완료한 사용자의 아이디를 세션에 저장하는 메소드
* @param session 세션 객체
* @param userID 사용자 아이디
*/
public void setSession(HttpSession session, String userId){
//이순간에 Session Binding이벤트가 일어나는 시점
//name값으로 userId, value값으로 자기자신(HttpSessionBindingListener를 구현하는 Object)
session.setAttribute(userId, this);//login에 자기자신을 집어넣는다.
}
/*
* 입력받은 세션Object로 아이디를 리턴한다.
* @param session : 접속한 사용자의 session Object
* @return String : 접속자 아이디
*/
public String getUserID(HttpSession session){
return (String)loginUsers.get(session);
}
/*
* 현재 접속한 총 사용자 수
* @return int 현재 접속자 수
*/
public int getUserCount(){
return loginUsers.size();
}
/*
* 현재 접속중인 모든 사용자 아이디를 출력
* @return void
*/
public void printloginUsers(){
Enumeration e = loginUsers.keys();
HttpSession session = null;
System.out.println("===========================================");
int i = 0;
while(e.hasMoreElements()){
session = (HttpSession)e.nextElement();
System.out.println((++i) + ". 접속자 : " + loginUsers.get(session));
}
System.out.println("===========================================");
}
/*
* 현재 접속중인 모든 사용자리스트를 리턴
* @return list
*/
public Collection getUsers(){
Collection collection = loginUsers.values();
return collection;
}
}
/*
* 본 예제소스는 우리가 구현하려고 예제에서 가장 핵심적인 부분을 맡고있다.
* 여기서 HttpSessionBindingListener는 서블릿 컨테이너에서 세션이 끊길때
* (valueUnBound)와 이를 구현하는 오브젝트가 해당 세션에 setAttribute 될때
* (valueBound)를 호출합니다. 굳이 이를 구현하는이유는 세션이 끊기는 시점을 정확히 잡아내기 위해서다.
* 사용자가 로그아웃버튼을 누를시도 있지만 세션이 타임아웃되는경우도 세션이 끊겨야 하기 때문입니다.
*/
=============================== 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");
%>
'IT기술 > JAVA' 카테고리의 다른 글
jsp 넘어온 값(request) 확인 (0) | 2018.10.06 |
---|---|
JSP 기본(내장) 객체 - 세션(session) (0) | 2017.03.24 |
servlet 이란 무엇인가? (0) | 2017.03.22 |
JSP 파일 업로드 시키기. cos 모듈을 이용, 이클립스 사용 (0) | 2016.05.16 |
윈도우 10 자바 환경변수 설정하기 (0) | 2016.05.13 |