본문 바로가기
공부/Spring

[chap13] MVC 3 : 세션, 인터센터, 쿠키

by JERO__ 2022. 6. 2.

13장. MVC 3 : 세션, 인터센터, 쿠키

로그인 상태 유지하기

방법 : 세션, 쿠키

1. 세션 : HttpSession 사용하기

요구사항

다음 두 가지 중 한 가지를 사용하면 된다.

  • 요청 매핑 애노테이션 적용 메서드에, HttpSession 파라미터 추가
@PostMapping
public String form(LoginCommand loginCommand, Erros errors, HttpSession session) {
		...
}

요청 매핑 애노테이션 적용 메서드에, HttpServletRequest 파라미터 추가 → HttpSession 구하기

@PostMapping
public String form(LoginCommand loginCommand, Erros errors, HttpServletRequest request) {
		HttpSession session = request.getSession();
}

그렇다면, 인증 후 인증 정보를 세션에 저장은?

  • 로그인에 성공하면, authInfo속성에 인증 정보 객체를 저장하도록 코드 추가
@PostMapping
public String submit(LoginCommand loginCommand, Erros errors, HttpSession session) {
		...
		session.setAttribute("authInfo", autoInfo);         // 추가
}

로그아웃 : HttpSession을 제거하면 된다

@RequestMapping("logout")
public class LogoutController {
		session.invalidate();              // 제거
		return "redirect:/main";
}

인터셉터

사용이유

  • 로그인 여부 확인을 위해서 구현한 컨트롤러 코드마다 세션 확인 코드를 삽입한다 → 많은 중복
  • 다수의 컨트롤러에 대해 동일한 기능을 적용할 때 사용할 수 있다.

1. HandlerInterceptor 인터페이스 구현

  • 공통기능을 넣을 수 있는 시점
    • 컨트롤러(핸들러) 실행 전 boolean preHandle
      • false를 리턴하면 컨트롤러를 실행하지 않음 : 검증
    • 컨트롤러(핸들러) 실행 후, 아직 뷰를 실행하기 전 void postHandle
      • 정상 실행 이후, 추가 기능 구현
    • 뷰를 실행한 이후 void afterCompletion
      • 컨트롤러 실행 이후 익셉션 로그를 남기거나, 실행 시간을 기록

2. HandlerInterceptor 설정

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
		
		@Override
		public void addInterceptors(InterceptorRegistry registry){
				registry.addInterceptor(authCheckInterceptor())
					.addPathPatterns("/edit/**");          
		}
}

쿠키

1. 사용방법

@GetMapping
public String form(LoginCommand loginCommand, 
						@CookieValue(value="REMEMBER", required=false) Cookie rCookie) {
						// 이름이 REMEMBER인 쿠키를 Cookie 타입으로 받음
						// 쿠키가 없을 수 있다 : required=false (기본값 true, 없으면 예외)

		if (rCookie != null) {       // 쿠키가 있으면
				loginCommand.setEmail(rCookie.getValue());
				loginCommand.setRememberEmail(true);
		}
		return "login/loginForm";
}

2. 생성하기

@PostMapping
public String submit(LoginCommand loginCommand, Erros errors, HttpSession session,
											HttpServletResponse response) {

		Cookie cookie = new Cookie("REMEMBER", loginCommand.getEmail());   // 쿠키생성
		cookie.setPath("/");
		cookie.setMaxAge(60*60*24*30);

		response.addCookie(cookie);        // 응답에 쿠키 추가
		return "login/loginSuccess";
}

요약

1. 쿠키

  1. 서버가 브라우저에 데이터(쿠키)를 넣음
  2. 브라우저는 해당 쿠키를 요청과 함께 보냄
  • 특징
    • 유효기간
    • 인증
    • 언어설정

2. 세션

1. 전제

HTTP는 무상태성(Stateless)이다 → 서버로 가는 모든 요청이 이전 리퀘스트와 독립적으로 이루어진다 → 요청이 끝나면, 서버는 너가 누군지 모른다!

2. 요청할 때마다 내가 누군지 알려줘야 한다 → 세션

  1. 제로는 로그인을 위해 ID, PASSWORD를 서버에 보낸다.
  2. 비밀번호가 맞다면, 서버는 세션 DB에 제로라는 유저를 생성한다.
    • 세션에는 별도의 ID가 있다.
    • 세션의 ID는 쿠키를 통해 브라우저에 저장됨
  3. 제로는 브라우저의 쿠키 통해 세션ID를 서버에 보낸다. (아직까지도 서버는 내가 누군지 모른다)
  4. 서버는 세션ID를 통해 세션 DB를 확인, 임을 확인한다.

모든 유저 정보는 서버에 있다. 유저는 세션 ID만 가질 뿐.

  • 세션을 이용해 iOS, Android 앱 만들 수 있지만, 쿠키는 사용할 수 없다(브라우저에만 존재) → 그렇다면? 토큰을 사용한다.
  • 토큰 : 이상하게 생긴 String
    • 토큰을 서버에 보내고, 서버는 세션 DB에서 해당 토큰과 일치하는 유저를 찾음

그렇다면, 요청이 있을때마다 서버는 쿠키를 받아 세션 ID를 보고 작업을 수행할 수 있다! → 유저가 늘어나면, DB리소스가 더 필요하다 →JWT 등☆장

3. JWT

  • 세션 DB를 갖을 필요 없다

JWT는 토큰 형식 ?

  • 토큰 : 이상하게 생긴 String, 엄청길다.
    • 쿠키는 공간 제약이 있지만, 토큰은 제약이 없음

토큰의 사용

서버는 토큰을 받으면, 유효한지 체크한다. → 제로로 인증한다.

세션 VS 토큰

세션

  1. 장점
  • 서버는 로그인 된 유저의 모든 정보를 저장 → 새로운 기능 추가가 가능하다.
  1. 단점
  • DB를 사고 유지해야한다.

토큰

  1. 장점
  • 서버가 아는 것은 토큰이 유효한가 여부 뿐
  1. 단점
  • 이미 저장된 토큰을 변경할 수 없다(브라우저에 저장됨) → 만료되기까지 유효
    • 코로나 QR코드도 JWT다.

댓글