Ryan's Log

Java Web 한개의 로그인만 허용하는 세션 본문

카테고리 없음

Java Web 한개의 로그인만 허용하는 세션

Ryan c 2016. 2. 11. 11:23
728x90

한개의 로그인만 허용하는 Session



한 사용자가 여러 컴퓨터에서 로그인 하더라도 마지막에 로그인 한 컴퓨터 혹은 브라우저의 Session만 유효하도록 제한하고자 한다면 HttpSessionBindingListener 인터페이스를 이용한다.




아래는 새로운 Session의 브라우저에서 같은 사용자로 로그인 시 이전에 로그인 된 브라우저의 세션을 invalidate 하는 소스이다.


우선 HttpSessionBindingListener를 구현하여 valueBound와 valueUnbound를 구현한다.

package org.starj.example.single_session;
import java.io.Serializable;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;


public class User implements HttpSessionBindingListener, Serializable {

	private static final long serialVersionUID = 0L;
	private HttpSession session;
	private String sessionId;
	
	private final String id;
	
	public User(String id){
		this.id = id;
	}

	//이 User객체게 session에 setAttribute 되는 시점에 실행됩니다.
	public void valueBound(HttpSessionBindingEvent event) {
		User user = (User)event.getValue();
		HttpSession session = event.getSession();
		user.sessionId = session.getId();
		user.session = session;
		
		//사용자 정보(사용자 id를 키값으로)를 맵에 담다둔다.
		Users.setUser(user.id, user);
	}

	// session 이 invalidated되거나 이 User객체가 session에서 removeAttribute된경우 실행됩니다.
	public void valueUnbound(HttpSessionBindingEvent event) {
		//User user = (User)event.getValue();
		Users.removeUser(id);
	}

	public HttpSession getSession() {
		return this.session;
	}

	public String getSessionId() {
		return this.sessionId;
	}

	public String getId() {
		return this.id;
	}

}


로그인 한 사용자 정보를 별도로 담아 둘 Map을 static으로 구현한다.

package org.starj.example.single_session;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lugam
 */
public class Users {

	private final static Map uniqueUsers = new HashMap();
	
	public static int getSize(){
		return uniqueUsers.size();
	}

	public static User getUser(String id){
		return uniqueUsers.get(id);
	}
	
	static void removeUser(String id){
		uniqueUsers.remove(id);
	}
	
	static void setUser(String id, User user){
		uniqueUsers.put(id, user);
	}
}


로그인 시 조건에 맞게 session.invalidate()를 실행한다.

String id = request.getParameter("id");

//이미 로그인 중인지 검사
User exists = Users.getUser(id);
if(exists != null && !session.getId().equals(exists.getSessionId())){
	//이미 다른 컴퓨터 또는 새로운 세션의 브라우저로 로그인함
	//이미 로그인된 계정은 강제로 로그아웃 시킴
	exists.getSession().invalidate();
	
	System.out.println(id + "는 다른 컴퓨터에서 로그인되어있었습니다. 다른 컴퓨터는 강제로 로그아웃됩니다.");
}

//제공된 id로 로그인 (기존 세션이 이미 있었다면 invalidated됨)
User user = new User(id);
session.setAttribute("user", user);
//session.setAttribute로 제공된 user객체가 HttpSessionBindingListener 인터페이스를 구현하고 있을경우
//User 객체 내 valueBound 메소드가 되며 이때 User의 uniqueUsers에 session을 포함한 User객체가 저장됩니다.
//이후 로그인시 uniqueUsers를 통해서 기존에 로그인된 id인지 판단하여 이미 로그인된 경우 강제로 session.invalidate()를 실행하여
//다른 컴퓨터또는 다른세션의 브라우저를 강제 로그아웃 시킵니다.
response.sendRedirect("./welcome.jsp");


이후 응용 하는것은 님 몫.



이를 응용하면 고갱님의 다양한 요구사항들에 대응할수 있다.



1. 여러대의 컴퓨터에서 다중으로 로그인 하여 사용하는 것은 막아주세요. 


2. 허나 한 컴퓨터에서 여러(종류)개의 브라우저를 열어 각각 로그인 하는것은 허용해 주세요.


3. 다른 컴퓨터에서 로그인 한 이후 기존 로그인 된 컴퓨터의 브라우저에서 다시 사용 하려는 경우 "다른 컴퓨터에서 로그인 하여 접속이 끊어졌습니다." 를 뿌려주세요."


4. 사용자의 session invalidate 시점에(혹은 로그아웃 할 때) 로그를 남기고 싶습니다.




소스 전체 참조 : 

one-session.zip


728x90