상태 정보란?
브라우저의 인증 상태를 확인하기 위한 정보
상태 정보 유지 기술
브라우저를 새로 고침할 때마다 계속해서 인증을 해줘야하는 번거로움을 없애고,
브라우저에 상태 정보를 저장하는 기술
상태정보를 브라우저가 설치된 컴퓨터에 저장
텍스트 형태의 상태정보만 저장
저장 가능한 데이터의 개수 및 크기 제한
사용 방법 간단
ex. 사용자 인증, 장바구니 기능
브라우저에서 서버로 전송되는 쿠키를 차단하면?
❗ 쿠키 기반의 상태 정보는 아예 사용 불가 ❗
브라우저에 저장되므로
❗ 누군가가 쿠키 정보를 몰래 보거나 조작 가능 ❗
상태정보를 서버에 저장
인증에 성공한 회원 아이디 정보를 쿠키 정보로 생성
생성된 쿠키 객체를 addCookie()
로 HTTP 응답 프로토콜에 포함되도록 작성
👉 쿠키 정보는 HTTP 응답 브라우저에 전송될 때 name: value
쌍으로 message-header
에 포함
브라우저로 쿠키 정보 전달
브라우저가 서버에 다시 요청할 때 HTTP 요청 message-header
에 쿠키 정보가 포함되어 서버에 전달
도메인, 패스, 쿠키 유효시간 등을 설정할 때 사용
메소드 | 기능 |
---|---|
void setDomain(String domain) | 쿠키 도메인 설정 |
void setPath(String uri) | 쿠키 패스 설정 |
void setMaxAge(int expiry) | 쿠키 유효시간 설정 |
LoginServlet
파일에 쿠키 정보 사용하기 if(user != null) { // 아이디를 이용한 검색 결과가 있는 경우
if(user.getPassword().equals(password)) { // 비밀번호도 체크
// 로그인에 성공한 경우, 회원 정보를 쿠키에 저장하여 브라우저로 전송한다.
Cookie userId = new Cookie("userId", user.getId()); // 텍스트 형태의 데이터만 저장 가능
response.addCookie(userId); // 쿠기 정보를 브라우저에 전달
// userId.setPath("");
// userId.setDomain("");
// userId.setMaxAge(10);
// 리디렉트 사용
// response.sendRedirect("getBoardList.do");
// 포워딩 사용
// RequestDispatcher dispatcher = request.getRequestDispatcher("getBoardList.do");
// dispatcher.forward(request, response);
} else { // 아이디는 맞는데, 비밀번호 틀린 경우
response.sendRedirect("login.html");
}
} else { // 아이디에 해당하는 회원이 없는 경우
response.sendRedirect("login.html");
}
GetBoardServlet
, GetBoardListServlet
, DeleteBoardServlet
파일에 쿠키 적용 // 상태 정보 체크
String userId = null;
// 브라우저가 message-header를 통해 전송한 쿠키 정보들을 추출
// getCookies() --> 요청 프로토콜 header에 있는 쿠키 목록들을 배열로 return
Cookie[] cookieList = request.getCookies();
if (cookieList == null) { // 쿠키 목록 없을 때
response.sendRedirect("login.html");
} else { // 쿠키 목록 있을 때
for (Cookie cookie : cookieList) {
if (cookie.getName().equals("userId")) { // name이 userId인 데이터가 있다면
userId = cookie.getValue();
}
}
if (userId == null) { // name이 userId인 데이터가 없다면
response.sendRedirect("login.html");
}
}
HttpServletRequest
의 getSession()
메소드로 생성 unique
한 세션ID👉 세션 ID로 각 브라우저는 고유한 세션 객체를 유지
브라우저가 서버에 처음 요청
message-header
에 포함된 쿠키 정보 추출추출된 쿠키 목록에 해당 서버에서 전송한 세션 ID
가 있는지 확인
만약 세션 ID
가 존재하지 않는다면?
새로운 세션 객체를 생성
세션 객체가 생성되는 순간, 동시에 생성되는 세션 ID
를 이용하여 쿠키 객체 생성
쿠키를 HTTP 응답 프로토콜에 설정하여 브라우저에 전송
두번째 요청 👉 세션 재사용
HTTP 요청 프로토콜 message-header
에 포함된 쿠키 정보 추출
추출된 쿠키 목록에 해당 서버에서 전송한 세션 ID
가 있는지 확인
브라우저가 만약 쿠키정보(세션 ID
)를 가지고 있다면?
쿠키 정보를 헤더에 세팅한 후 서버에 전달
= 해당하는 세션 객체를 return
request
정보를 전달세션 ID
가 존재함세션 ID
가 존재하지 않는다면?👉 브라우저 종료 시, 세션도 종료
메서드 | 기능 |
---|---|
void setAttribute(String name, Object value) | 세션에 name-value 쌍의 데이터를 저장 |
Object getAttribute(String name) | 세션에 저장된 데이터를 리턴 |
Enumeration getAttributeNames() | 세션에 저장된 데이터의 name 목록을 Enumeration 타입으로 리턴 |
void removeAttribute(String name) | 세션에 저장된 데이터를 삭제 |
String getId() | 생성된 세션 객체의 세션 ID를 리턴 |
boolean isNew() | 처음 생성된 세션인지를 리턴 |
long getCreationTime() | 세션이 생성된 시간을 리턴 |
long getLastAccessTime() | 마지막으로 세션이 사용된 시간을 리턴 |
void setMaxInactiveInterval(int second) | 브라우저가 서버에 아무런 요청을 하지 않을 때, 얼마까지 세션을 유지할 것인지를 설정 (기본 30분) |
int getMaxInactiveInterval() | 설정된 세션의 유효시간을 리턴 |
void invalidate() | 브라우저와 매핑된 세션을 강제로 종료 |
request.getSession()
로 세션 생성HttpSession session = request.getSession(); // 브라우저의 정보 + 시간 정보 => unique 한 세션 ID 생성
String seesionId = session.getId(); // 세션 ID 가져오기
System.out.println("세션 ID : " + seesionId);
출력
콘솔창 출력 결과
새로고침하면 계속 같은 세션 ID가 계속 출력
❗ 새로운 브라우저로 다시 하면? 다른 세션 ID가 출력 ❗
새로운 세션 객체에 세션 ID가 만들어짐
응답 프로토콜에서 쿠키 형태로 브라우저에 전달
해당 브라우저는 같은 도메인에 요청했기 때문에,
해당 도메인에서 저장된 같은 세션 ID가 계속 전달
HttpSession session = request.getSession(); // 브라우저의 정보 + 시간 정보 => unique 한 세션 ID 생성
String seesionId = session.getId(); // 세션 ID 가져오기
if(session.isNew()) {
System.out.println(seesionId + "---> GetBoardListServlet에서 처음 생성된 세션이다.");
} else {
System.out.println(seesionId + "---> 이전에 생성된 세션의 재사용이다.");
}
HttpSession session = request.getSession(); // 브라우저의 정보 + 시간 정보 => unique 한 세션 ID 생성
// 세션으로부터 userId, userName 이라는 이름으로 등록된 상태 정보가 있는 지 확인
String userId = (String) session.getAttribute("userId");
String userName = (String) session.getAttribute("userName");
if(userId == null) { // 세션ID가 없다면 로그인부터 하기
response.sendRedirect("login.html");
}
GetBoardListServlet
)에서 받은 해당 세션 ID를 받고,⇒ 즉, request
될때마다 매번 새로운 세션 ID가 만들어지는 것이 아님
if(user != null) { // 아이디를 이용한 검색 결과가 있는 경우
if(user.getPassword().equals(password)) { // 비밀번호도 체크
// 로그인에 성공한 경우, 회원 정보를 세션에 저장하여 브라우저로 전송한다.
HttpSession session = request.getSession(); // 세션ID 받기
session.setAttribute("userId", user.getId()); // userId 저장
session.setAttribute("userName", user.getName()); // userName 저장
// 리디렉트 사용
// response.sendRedirect("getBoardList.do");
// 포워딩 사용
// RequestDispatcher dispatcher = request.getRequestDispatcher("getBoardList.do");
// dispatcher.forward(request, response);
} else { // 아이디는 맞는데, 비밀번호 틀린 경우
response.sendRedirect("login.html");
}
} else { // 아이디에 해당하는 회원이 없는 경우
response.sendRedirect("login.html");
}
브라우저가 살아있는 동안 다른 서블릿에서 공유
HttpSession
, HttpServletRequest
, ServletContext
객체를 통해 정보를 공유
만약 로그인 시 인증에 성공했다면?
다른 서블릿에서도 회원 아이디, 이름 등 정보를 공유하고
세션 객체로 저장했을 경우 세션에 저장하여 공유됨
세션이 아닌 HttpServletRequest
를 통해 정보를 공유하여 해결
HttpServletRequest
요청이 들어올 때,
→ Servlet Container
가 HttpServletRequest
객체를 생성하고
→ 브라우저로 응답이 전송되는 순간 자동으로 삭제됨
HttpServletRequest
객체가 서버 메모리에 유지되는 시간