쿠키, 세션, 캐시

김재민·2022년 4월 22일
0

HTTP 특징

  1. Stateless ( 무상태성 )
    클라이언트의 상태 정보를 가지지 않는 서버 처리 방식.
    클라이언트와 첫 번째 통신에서 데이터를 주고 받았다 해도, 다음에 이전 데이터를 유지하지 않음
  1. Connectionless ( 비연결성 )
    클라이언트가 서버에 요청을 했을 때, 그 요청에 맞는 응답을 보낸 후 연결을 끊는 방식

상태 유지 (Stateful)의 필요성

HTTP 요청은 Stateless하기 때문에 정보가 유지 되지 않음. 
우리가 페이지를 이동하더라도 로그인 상태를 유지하기 위해,
장바구니에 구매하고 싶은 목록들을 저장하기 위해선 데이터를 유지해야할 필요가 있음.
HTTP의 무상태성을 보완하기 위해 사용되는 도구가 쿠키와 세션

1. 쿠키(Cookie)

사용자의 브라우저에 저장되고, 통신할 때 HTTP 헤더에 포함되는 텍스트 데이터 파일
이름, 값 만료기간(지정 가능), 경로 정보가 있고 키와 값으로 구성되어 있음
해당 사용자의 컴퓨터를 사용한다면 누구나 쿠키에 입력된 값을 쉽게 확인 가능 -> 보안성이 낮음

쿠키 통신방식

(1) 최초 통신에서는 쿠키값이 없으므로, 일단 클라이언트는 Request를 한다.
(2) 서버에서 클라이언트가 보낸 Request Header에 쿠키가 없는지 확인하고 판별. -> 통신 상태(UserID, Password, 조작상태, 방문횟수 등)를 저장한 쿠키를 Response한다.
(3) 클라이언트의 브라우저가 받은 쿠키를 생성 / 보존한다.
(4) 두번째 연결부터는, HTTP Header에 쿠키를 실어서 서버에 Request한다.

2. 세션(Session)

서버에 저장되는 쿠키, 클라이언트와 서버의 통신 상태, 주로 중요한 데이터를 저장 시 사용
브라우저를 종료할 때까지 유지됨
사용자 로컬이 아닌 서버에 직접 저장되므로, 세션 내의 데이터를 탈취하는 것은 어려움 ->보안성이 비교적 높음

세션 통신방식

(1) 클라이언트가 서버에 접속 시, 세션 ID를 발급
(2) 서버에서는 클라이언트로 발급해준 세션 ID를 쿠키를 이용해서 저장
(3) 클라이언트는 다시 페이지에 접속할 때, 쿠키에 저장된 세션 ID를 서버에 전달
(4) 서버는 Request Header에 쿠키 정보(세션ID)로 클라이언트를 판별

세션 취약점

세션 해킹 : 홈페이지 관리자의 Session Id를 탈취 -> Cookie값을 관리자의 Session Id로 변경 -> 관리자 권한으로 이용

예방법 : 세션에 로그인 했을 때의 IP를 저장 -> 페이지를 이동 시마다, 현재 IP와 세션의 IP / 브라우저 정보(UserAgent)가 같은지 검사

3. 캐시(Cache)

리소스 파일들의 임시 저장소
같은 웹 페이지에 접속할 때 사용자의 PC에서 로드하므로 서버를 거치지 않아도 됨
이전에 사용되었던 데이터는 다시 사용될 가능성이 높다 -> 그래서 다시 사용될 확률이 있는 데이터들을 빠르게 접근 가능한 저장소에 저장
=> 페이지 로딩 속도를 개선


스프링 세션 설정

Spring에서 세션은 HttpSession클래스를 이용해 처리

Spring Web MVC 에서는 HttpSession을 주입해야할 때, 내부적으로 Servlet Container에게 Session을 획득하는 방법이 2가지로 나뉨

1. 컨트롤러에서 @Autowired를 통해 주입받음.
2. 요청 매핑 어노테이션 적용 메서드에 HttpSession 파라미터를 추가
3. 요청 매핑 어노테이션 적용 메서드에 HttpServletRequest 파라미터를 추가하고,
   HttpServletRequest를 이용해서 HttpSession을 구함
4. @SessionAttribute, @ModelAttribute로 주입받음

방법 1
@Autowired로 주입받기

setAttribute, getAttribute 등 메서드 호출 시 session 요청/생성

@Controller
public class HelloController{
	
    @Autowired
    private HttpSession session;

	@PostMapping("/hello2")
    public String submit(CommandObj cmdObj, Errors errors){
    	session.setAttribute("name", Object);
        return "test";
    }

}

방법 2
메서드에서 주입받기(HttpSession)

form 메서드 호출 시 session 요청/생성

@PostMapping
public String form(CommandObject cmdObj, Errors errors, HttpSession session) {
    session.setAttribute("name", Object);
    Object obj = session.getAttribute("name");
    session.removeAttribute("name");
    boolean isNew = session.isNew();
    session.invalidate(); //세션 삭제(로그아웃)
}

방법 3
메서드에서 주입받기(HttpServletRequest)

@PostMapping
public String form(CommandObject cmdObj, Errors errors, HttpServletRequest req) {
    HttpSession session = req.getSession();
    // session 사용
}

방법 4
@SessionAttribute, @ModelAttribute로 주입받기

이 방식은 Session에 이미 저장된 데이터를 조회할 때 적합, 메서드를 호출할 때 Session이 요청/생성됨

  1. @SessionAttribute를 컨트롤러에 추가함으로써 세션단위로 스코프를 지정하도록 명시
  2. @ModelAttribute을 선언함으로써 Session에서 "hello"라는 이름을 가진 오브젝트를 조회. 그리고 Object형태로 변환해 주입
@Controller
@SessionAttribute("hello")
public class HelloController {
	@PostMapping("/hello")
    public String submit(Model model, @ModelAttribute("hello") Object obj) {
        model.addAttribute("hello", obj.helloEvery());
		return "test";
	}
}

4. Spring 쿠키 설정

스프링에서 쿠키는 @CookieValue 어노테이션을 사용하여 요청 매핑 어노테이션 적용메서드에 Cookie타입 파라미터에 적용하여 사용 가능하다.

@GetMaaping
public String form(
    LoginCommand loginCommand,
    @CookieValue(value = "cookie_name", required = false) Cookie rCookie
) {
    //Cookie 값 얻기, 설정
    String cValue = rCookie.getValue();
    rCookie.setValue("New Value");
    rCookie.setPath("/");
    rCookie.setMaxAge(60 * 60 * 24 * 30);
    rCookie.setSecure(true);
    rCookie.setHttpOnly(true);
    boolean cookieisHttpOnly = rCookie.isHttpOnly();
}

Session은 Request를 받아 서버에 저장했다면, Cookie는 클라이언트로 Response를 주어야한다. HttpServletResponse를 통해 설정 가능

@GetMaaping
public String form( LoginCommand loginCommand, HttpServletResponse res) {
	Cookie myCookie = new Cookie("cookie_name", "value");
    //Cookie 값 얻기, 설정
    //설정 생략
    res.addCookie(myCookie);
}



참고1 https://ryusae.tistory.com/7
참고2 https://velog.io/@gwanuuoo/%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%EC%BA%90%EC%8B%9C%EB%9E%80

profile
어제의 나보다 나은 오늘의 내가 되자!🧗‍♂️

0개의 댓글