목표 : 웹 어플리케이션에서 로그인을 처리할 때 쿠키와 세션을 어떻게 사용하는지 정리
쿠키(Cookie)
를 이용하면 클라이언트는 매번 로그인정보를 가지고 요청할 필요가 없다.쿠키는 로그인구현을 담당하는 컨트롤러에서 생성후 HttpServletResponse 객체에 담아서 응답해주면 된다.
Cookie
객체 2번재 파라미터는 String 타입이 와야하기 때문에 로그인객체의 id값인 int 형을 String 으로 형변환 하였다. @PostMapping("/login")
public String login(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response){
// 생략 ...
// 로그인 성공 처리(세션 쿠키) -> 브라우저 종료 시 모두 종료
Cookie idCookie = new Cookie("memberId", String.valueOf(loginMember.getId()));
response.addCookie(idCookie);
return "redirect:/";
}
@CookieValue
어노테이션을 사용하면 된다. @GetMapping("/")
public String homeLogin(@CookieValue(name="memberId",required = false) Long memberId,
Model model){
if(memberId == null)
return "home";
// 로그인
Member loginMember = memberRepository.findById(memberId);
if(loginMember == null)
return "home";
model.addAttribute("member",loginMember);
return "loginHome";
}
세션은 쿠키와 다르게 서버에 저장하고 관리하기 때문에 쿠키보다 안전하다.
sessionId
는 임의의 식별자를 지정하기 때문에 역추적이 안된다.Session 은 웹 어플리케이션에서 꼭 필요하므로 서블릿에서 제공하는
HttpSession
을 사용하면 된다.
JSESSIONID
로 지정 되어 있고 Value 에는 추적불가능한 랜덤값인 sessionId가 들어가 있다.getSession()
: 이 메서드를 통해 session 을 생성하고 조회한다.setAttribute()
메서드에는 sessionId 와 value 를 넣는다.invalidate()
메서드는 세션을 제거해준다.@PostMapping("/login")
public String loginV3(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletRequest request){
// 로직 생략...
// HttpSession 이용
// 세션이 있으면 있는 세션 반환, 없으면 신규 세션을 생성해서 반환
HttpSession session = request.getSession();
// 세션에 로그인 회원 정보를 보관
session.setAttribute(SessionConst.LOGIN_MEMBER,loginMember);
return "redirect:/";
}
@PostMapping("/logout")
public String logoutV3(HttpServletRequest request){
HttpSession session = request.getSession(false);
if(session != null)
session.invalidate();
return "redirect:/";
}
웹 브라우저의 개발자 모드를 들어가서 Cookies 목록을 보면 쿠키이름에는 HttpSession 이 지원하는 JSESSIONID 가 들어가 있고 Value 에는 서버에서 임의로 지정한 sessionId 가 담겨져 있는걸 확인할 수 있다.
웹 어플리케이션 로직을 짤 때 세션을 끊는 로직은 보통 /logout 같이 웹 브라우저에서 로그아웃 버튼을 누를 때 동작한다, 하지만 일반인들은 웹 브라우저를 끄는 경우가 대부분이다.
application.yml
에서 세션 타임아웃을 설정할 수 있다. server.servlet.session.timeout=1800 #30분
session.setMaxInactiveInterval()
메서드를 사용하면 된다.