상태 정보 유지 Cookie 와 Session, 정보 공유 메서드

Yeppi's 개발 일기·2022년 5월 25일
0

Servlet&JSP

목록 보기
7/13
post-thumbnail

1. 상태정보 유지

1) 개념

  • 상태 정보란?
    브라우저의 인증 상태를 확인하기 위한 정보

  • 상태 정보 유지 기술
    브라우저를 새로 고침할 때마다 계속해서 인증을 해줘야하는 번거로움을 없애고,
    브라우저에 상태 정보를 저장하는 기술

  • 상태 정보 유지 기술은 쿠키와 세션이 있다


쿠키

상태정보를 브라우저가 설치된 컴퓨터에 저장

  • 텍스트 형태의 상태정보만 저장

  • 저장 가능한 데이터의 개수 및 크기 제한

  • 사용 방법 간단
    ex. 사용자 인증, 장바구니 기능

  • 브라우저에서 서버로 전송되는 쿠키를 차단하면?
    ❗ 쿠키 기반의 상태 정보는 아예 사용 불가 ❗

  • 브라우저에 저장되므로
    ❗ 누군가가 쿠키 정보를 몰래 보거나 조작 가능 ❗


세션

상태정보를 서버에 저장

  • 모든 타입의 데이터 저장
    • 객체 형태의 데이터도 가능
  • 서버 메모리가 허용하는 범위내에서 데이터 얼마든지 저장
  • 세션은 Map 과 유사한 형태


2. Cookie 사용하기

1) 쿠키 저장 및 전송

  1. 인증에 성공한 회원 아이디 정보를 쿠키 정보로 생성

  2. 생성된 쿠키 객체를 addCookie() 로 HTTP 응답 프로토콜에 포함되도록 작성
    👉 쿠키 정보는 HTTP 응답 브라우저에 전송될 때 name: value 쌍으로 message-header에 포함

  3. 브라우저로 쿠키 정보 전달

  4. 브라우저가 서버에 다시 요청할 때 HTTP 요청 message-header에 쿠키 정보가 포함되어 서버에 전달



2) 쿠키 설정 및 활용

쿠키 메서드 path, domain, maxage

  • 도메인, 패스, 쿠키 유효시간 등을 설정할 때 사용

    메소드기능
    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");
			}
		}


3. Session 사용하기

1) 세션 동작 원리

세션 객체

  • HttpServletRequestgetSession() 메소드로 생성
  • 서버 메모리에 생성되는 순간, 다른 세션 객체와 구분하기위한 세션 ID 생성
    • unique 한 세션ID

세션 ID

  • 요청을 전송한 브라우저 정보 + 요청 시간 조합
  • 쿠키로 생성

👉 세션 ID로 각 브라우저는 고유한 세션 객체를 유지

동작 순서

브라우저가 서버에 처음 요청

  1. HTTP 요청 프로토콜 message-header 에 포함된 쿠키 정보 추출
    • 브라우저가 서버에 처음 요청했을 때 리퀘스트 정보가 자동으로 생성
  1. 추출된 쿠키 목록에 해당 서버에서 전송한 세션 ID가 있는지 확인

  2. 만약 세션 ID가 존재하지 않는다면?
    새로운 세션 객체를 생성

  3. 세션 객체가 생성되는 순간, 동시에 생성되는 세션 ID를 이용하여 쿠키 객체 생성

  4. 쿠키를 HTTP 응답 프로토콜에 설정하여 브라우저에 전송


두번째 요청 👉 세션 재사용

  1. HTTP 요청 프로토콜 message-header 에 포함된 쿠키 정보 추출

  2. 추출된 쿠키 목록에 해당 서버에서 전송한 세션 ID가 있는지 확인

  3. 브라우저가 만약 쿠키정보(세션 ID)를 가지고 있다면?
    쿠키 정보를 헤더에 세팅한 후 서버에 전달
    = 해당하는 세션 객체를 return

  1. 이때 요청프로토콜의 모든 정보를 채워서 request 정보를 전달
    • 전달하는 정보의 헤더에는 세션 ID가 존재함
  1. 만약 세션 ID가 존재하지 않는다면?
    새로운 세션 객체를 생성


👉 세션 : 브라우저당 서버메모리에 하나씩 생성

👉 브라우저 종료 시, 세션도 종료



2) HttpSession 메서드

메서드기능
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()브라우저와 매핑된 세션을 강제로 종료


📌세션ID 실습📌

  • request.getSession()로 세션 생성
  • GetBoardListServlet.java
HttpSession session = request.getSession(); // 브라우저의 정보 + 시간 정보 => unique 한 세션 ID 생성
String seesionId = session.getId(); // 세션 ID 가져오기
System.out.println("세션 ID : " + seesionId);
  • 출력

    1. 브라우저에 http://localhost:8080/BoardWeb/getBoardList.do

    2. 콘솔창 출력 결과

    3. 새로고침하면 계속 같은 세션 ID가 계속 출력

  • 새로운 브라우저로 다시 하면? 다른 세션 ID가 출력 ❗

    • 새로운 세션 객체에 세션 ID가 만들어짐

    • 응답 프로토콜에서 쿠키 형태로 브라우저에 전달

    • 해당 브라우저는 같은 도메인에 요청했기 때문에,
      해당 도메인에서 저장된 같은 세션 ID가 계속 전달


  • 크롬 브라우저, 엣지 브라우저 2군데에서 실행했을 때
    • 이전 세션의 재사용은 크롬이고, 새로 생성된 세션은 엣지
HttpSession session = request.getSession(); // 브라우저의 정보 + 시간 정보 => unique 한 세션 ID 생성
String seesionId = session.getId(); // 세션 ID 가져오기

if(session.isNew()) {
	System.out.println(seesionId + "---> GetBoardListServlet에서 처음 생성된 세션이다.");
} else {
	System.out.println(seesionId + "---> 이전에 생성된 세션의 재사용이다.");
}


👉 세션 객체는 브라우저 하나당 서버 메모리에 하나씩 생성되는 객체

👉 세션 ID만 브라우저의 응답 프로토콜의 헤더에 저장되어 전송



📌인증 상태 유지 실습📌

  • 세션 ID가 브라우저에 전송
  • 로그인 버튼 누르면, 브라우저가 죽지 않고, 로그인서블렛 실행
  • GetBoardListServlet.java
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");
}

  • Login 기능
    • 위(GetBoardListServlet)에서 받은 해당 세션 ID를 받고,
      세션 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");
}


4. 정보 공유

1) 정보 공유 란?

브라우저가 살아있는 동안 다른 서블릿에서 공유

  • HttpSession, HttpServletRequest, ServletContext 객체를 통해 정보를 공유

  • 만약 로그인 시 인증에 성공했다면?
    다른 서블릿에서도 회원 아이디, 이름 등 정보를 공유하고
    세션 객체로 저장했을 경우 세션에 저장하여 공유됨



2) 정보 공유 메서드



3) HttpServletRequest

유효 범위

  • 세션에 저장되는 데이터가 증가하면?
    서버 메모리 공간이 부족해짐
  • 세션이 아닌 HttpServletRequest 를 통해 정보를 공유하여 해결

  • HttpServletRequest 요청이 들어올 때,
    Servlet ContainerHttpServletRequest 객체를 생성하고
    → 브라우저로 응답이 전송되는 순간 자동으로 삭제됨

유효 시간은

👉 HttpServletRequest 객체가 서버 메모리에 유지되는 시간

👉 서버로부터 응답이 전송되기 전 까지의 시간

profile
imaginative and free developer. 백엔드 / UX / DATA / 기획에 관심있지만 고양이는 없는 예비 개발자👋

0개의 댓글