마지막으로 추가할 클래스는 각 클라이언트별 세션을 담당할 HttpSession 클래스로 서블릿에서 세션 데이터에 접근할 때 사용한 클래스다. HttpSession 은 다음과 같이 구현 가능하다.
- HttpSession.java
import java.util.HashMap;
import java.util.Map;
public class HttpSession {
private Map<String, Object> values = new HashMap<String, Object>();
private String id;
public HttpSession(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setAttribute(String name, Object value) {
values.put(name, value);
}
public Object getAttribute(String name) {
return values.get(name);
}
public void removeAttribute(String name) {
values.remove(name);
}
public void invalidate() {
HttpSessions.remove(id);
}
}
마지막으로 HttpRequest 에서 클라이언트에 해당하는 HttpSession 에 접근할 수 있도록 메서드를 추가한다.
- HttpRequest.java
public class HttpRequest {
...
public HttpSession getSession() {
return HttpSessions.getSession(getCookies().getCookie("JSESSIONID"));
}
}
지금까지 과정을 통해 세션 관리를 위한 모든 작업을 완료했다. 이제 직접 구현한 웹 서버에 세션을 추가했으니 로그인을 완료했을 때 logined=true 와 같이 쿠키 값을 추가하는 것이 아니라 User 객체를 추가해 로그인 여부를 판단하도록 기존 코드를 변경한다.
- LoginController.java
public class LoginController extends AbstractController {
@Override
public void doPost(HttpRequest request, HttpResponse response) {
User user = DataBase.findUserById(request.getParameter("userId"));
if (user != null) {
if (user.login(request.getParameter("password"))) {
// response.addHeader("Set-Cookie", "logined=true");
HttpSession session = request.getSession();
session.setAttribute("user", user);
response.sendRedirect("/index.html");
} else {
response.sendRedirect("/user/login_failed.html");
}
} else {
response.sendRedirect("/user/login_failed.html");
}
}
}
위와 같이 세션에 추가한 User 는 로그인 유무를 판단하기 위해 다음과 같이 활용할 수 있다.
- ListUserController.java
public class ListUserController extends AbstractController {
@Override
public void doGet(HttpRequest request, HttpResponse response) {
if (!isLogined(session.getSession())) {
response.sendRedirect("/user/login.html");
return;
}
...
}
private static boolean isLogined(HttpSession session) {
Object user = session.getAttribute("user");
if (user == null) {
return false;
}
return true;
}
}
지금까지 구현 과정을 통해 확인할 수 있듯이 세션을 활용하면 클라이언트와 서버 사이에 상태 공유를 위해 전달하는 데이터는 세션 아이디 뿐이다. 따라서 세션 아이디를 예측할 수 없도록 생성하는 것은 보안 측면에서 중요하다.
쿠키는 보안을 좀 더 강화하기 위해 domain, path, max-age, expires, secure 속성을 사용할 수 있다. 단순히 세션만 사용한다고 모든 보안 문제가 해결되지 않는다. 쿠키에서 사용할 수 있는 위 속성들을 통해 좀 더 보안을 강화한다.
지금까지 구현한 세션을 적용한 코드는 https://github.com/slipp/web-application-server 저장소의 was-step4-httpsession 브랜치에서 참고할 수 있다.
참고도서 : https://roadbook.co.kr/169
[신간안내] 자바 웹 프로그래밍 Next Step
● 저자: 박재성 ● 페이지: 480 ● 판형: 사륙배변형(172*225) ● 도수: 1도 ● 정가: 30,000원 ● 발행일: 2016년 9월 19일 ● ISBN: 978-89-97924-24-0 93000 [강컴] [교보] [반디] [알라딘] [예스24] [인터파크] [샘
roadbook.co.kr
'교재 실습 > 자바 웹 프로그래밍 Next Step' 카테고리의 다른 글
6.4.1 요구사항 (5) | 2025.05.14 |
---|---|
6.4 MVC 프레임워크 요구사항 1단계 (1) | 2025.05.12 |
6.3.3 모든 클라이언트의 세션 데이터에 대한 저장소 추가 (4) | 2025.05.07 |
6.3.2 쿠키를 활용해 아이디 전달 (4) | 2025.05.01 |
6.3.1 고유한 아이디 생성 (3) | 2025.04.30 |
댓글