티스토리 뷰

Web/Spring

[Spring] Cookie / Session

angelatto 2021. 3. 29. 21:50

HTTP는 무상태(stateless- 상태를 유지하지 않음) 프로토콜이다. 즉, 재요청 시 서버는 클라이언트를 기억하지 못한다. 

그래서 상태를 유지하기 위한 기술로 쿠키와 세션을 이용한다. 

즉, 쿠키나 세션방식을 이용해서 클라이언트가 옛날에 접속했던 클라이언트인지 기억해내는 것이다. 

 

※ Cookie

cf> document

tomcat.apache.org/tomcat-9.0-doc/servletapi/index.html

문자 데이터를 클라이언트에 저장하고, 서버에서 사용할 목적으로 활용

실행 흐름 클라이언트(브라우저) 서버
1   쿠키 생성 (이름:값) 해서 Response Header에 쿠키를 넘겨줌
2 쿠키 저장  
3   쿠키사용 (쿠키 값을 이용) - 서버가 자기가 사용할 목적으로 클라이언트에 쿠키를 저장한다.

※ 쿠키 생성 

 http:localhost:8080/webapp/

1. Expires

쿠키의 만기기간이 Session이라는 것은 브라우저가 닫히면 쿠키도 사라진다는 의미이다. 

쿠키 입장에서는 탭으로 열린 창들을 같은 브라우저이다. 

 

2.  Domain

Cookie cookie = new Cookie("uid", uid);
cookie.setDomain("192.168.x.x");

: 지정한 도메인으로 접근한 클라이언트만 쿠키를 받게 하겠다는 의미이다.

 

3. Path

Cookie cookie = new Cookie("uid", uid);
cookie.setPath("/");

: 지정한 경로(도메인 뒤의 경로의미)로 들어오는 요청에 대해서만 쿠키를 사용(쿠키를 읽을 수 있다)하게 하겠다는 의미이다. 

 

4. HttpOnly

Cookie cookie = new Cookie("uid", uid);
cookie.setHttpOnly(true);

: true이면 자바스크립트가 쿠키를 읽을 수 없다는 의미이다. 

 

5. Max-Age

 http://tomcat.apache.org/tomcat-9.0-doc/servletapi/index.html

음수 :  브라우저가 종료될 때 삭제

0 : 쿠키 삭제.

양수 : 해당 '초'만큼만 쿠키를 저장, 시간이 지나면 쿠키 삭제. 

 


※ 쿠키 사용 

[방법1]

@GetMapping("readCookie")
	public String readCookie(HttpServletRequest request) {
		Cookie[] cookieArr = request.getCookies();
		for(Cookie cookie : cookieArr) {
			logger.info(cookie.getName() + ": " + cookie.getValue());
			if(cookie.getName().equals("uid")) {
				logger.info(cookie.getValue() + " 활용하기");
			}
		}
		return "redirect:/exam06/content";
}

 

[방법2]

@GetMapping("readCookie")
	public String readCookie(@CookieValue String uid) {
		logger.info(uid + " 활용하기");
		return "redirect: /exam06/content";
	}

 

※ 쿠키 삭제

	@GetMapping("deleteCookie")
	public String deleteCookie(HttpServletResponse response) {
		Cookie cookie = new Cookie("uid", "");
		cookie.setMaxAge(0);
		response.addCookie(cookie);
		
		return "redirect:/exam06/content";
	}
			

[쿠키 특징]

- 쿠키의 값이 노출되면 보안에 취약해질 위험이 있다.  

- 쿠키는 암호화하는 것이 일반적이다. (=> JWT_ Json Web Token 이용 )

- JWT는 쿠키에 저장하는 것이 아니라 따로 요청 헤더에 넣어서 전달해야 한다. 

- 자바스크립트에서 쿠키를 획득할 수 있다. (보안을 위해서 이걸 막는 것이 setHttpOnly(true)이다. )

- 도메인을 여러개 지정할 수 있다. 

- 단점 : AJAX 처럼 비동기로 요청했을 때 도메인이 달라지면,, 쿠키를 받을 수 없다. 


쿠키와 세션의 큰 차이점 : 데이터가 저장되는 곳이 다르다. 

세션은 문자 데이터가 아니라 객체이다. (중요 !!! )

※ Session

객체를 "서버"에 저장하는 기술이다. 객체란 상태 데이터이다. 

동일한 클라이언트는 재요청 시 세션에 저장된 객체를 사용할 수 있다. 

JseesionID의 용도는 서버에 있는 세션 객체를 찾기 위함이다.

 

실행 흐름  client(browser) server(was)
1 최초 http 요청   
2   Session 객체(Jsession)가 생성됨
( ID : 고유xxx, 이름 : 객체 ) 
3   JsessionID를 쿠키에 넣어서 클라이언트로  전달한다. 
세션 객체 자체가 아니라 JsessionID만 ㅋ저장한다. 
4 쿠키에 있는 JsessionID 저장   
5 클라이언트의 재요청 - JsseionID를 들고  
6   넘어온 쿠키에 있는 JsessionID와 같은 세션 객체를 찾는다. 
7   찾은 객체를 사용한다. 

 

※ 세션에 객체 생성 

@GetMapping("/sessionSaveObject")
	public String sessionSaveObject(HttpSession session) {
		User user = new User();
		user.setUid("spring");
		session.setAttribute("user", user);		
		return "redirect:/exam06/content";
	}

 

※ 세션에서 객체 찾기 및 읽기

@GetMapping("/sessionReadObject")
	public String sessionReadObject(HttpSession session) {
		User user = (User)session.getAttribute("user");
		if(user != null) {
			logger.info(user.getUid());
		}
		return "redirect:/exam06/content";
	}

 

※ 세션에 객체 삭제 

@GetMapping("/sessionRemoveObject")
	public String sessionRemoveObject(HttpSession session) {
		// 개별 객체를 삭제할 때 
		session.removeAttribute("user");
		
		// 세션에 저장된 모든 객체를 삭제할 경우 
		session.invalidate();
		return "redirect:/exam06/content";
	}