도메인
로그인 상태를 유지하기 위해 쿼리 파라미터를 계속 유지하면서 보내는 것은 매우 어렵고 번거로움 > 쿠키를 사용!!
쿠키의 종류
LoginController.java
//로그인 성공 처리
//쿠키에 시간 정보를 주지 않으면 세션 쿠키(브라우저 종료시 모두 종료)
Cookie idCookie = new Cookie("memberId",String.valueOf(loginMember.getId()));
response.addCookie(idCookie);
로그인에 성공하면 쿠키를 생성하고 HttpServletResponse에 담음
HomeController.java
@GetMapping("/")
public String homeLogin(
@CookieValue(name="memberId",required = false) Long memberId, Model model){
//로그인 하지 않은 사용자도 들어와야하기때문에 required = false
//쿠키값은 자동으로 타입 컨버팅 해주어서 Stirng -> Long으로 받을 수 있음
if(memberId==null) {
return "home";
}
//로그인에 성공
Member loginMember = memberRepository.findById(memberId);
//디비에 없을 때(로그인 쿠키가 있어도 회원이없으면)
if(loginMember==null){
return "home";
}
model.addAttribute("member",loginMember);
return "loginHome";
}
LoginController.java
@PostMapping("/logout")
public String logout(HttpServletResponse response){
//쿠키를 없애는 방법 > 쿠키의 시간을 없앰
expireCookie(response,"memberId");
return "redirect:/";
}
private void expireCookie(HttpServletResponse response, String cookieName) {
Cookie cookie=new Cookie(cookieName,null);
cookie.setMaxAge(0);
response.addCookie(cookie);
}
쿠키를 사용해서 로그인Id를 전달해서 로그인을 유지할 수 있지만 심각한 보안 문제 발생
Cookie: mySessionId=zz0101xx-bab9-4b92-9b32-dadb280f4b61
세션의 사용으로 쿠키의 보안 문제 해결
Cookie: JSESSIONID=5B78E23B513F50164D6FDD8C97B0AD05
login
//세션이 있으면 있는 세션을 반환, 없으면 신규 세션을 생성해서 반환
HttpSession session = request.getSession();
//세션에 로그인 회원 정보 보관
session.setAttribute(SessionConst.LOGIN_MEMBER,loginMember);
logout
HttpSession session = request.getSession(false);
//true라고 하면 세션을 만들어버리기 때문에, 세션을 없애는게 목적이라서 false
if(session!=null){
session.invalidate();
//세션과 그 안에 있는 데이터가 다 날라감
}
home
HttpSession session = request.getSession(false);
//세션을 생성할 의도가 없기 때문에 false 로 둠
if(session==null){
return "home";
}
Member loginMember = (Member)session.getAttribute(SessionConst.LOGIN_MEMBER);
//세션에 회원 데이터가 없으면 home
if(loginMember==null){
return "home";
}
//세션이 유지되면 로그인으로 이동
model.addAttribute("member",loginMember);
return "loginHome";
request.getSession(false)
: 세션을 찾아서 사용하는 시점에는 false 옵션을 사용해서 세션을 생성하지 않음session.getAttribute(SessionConst.LOGIN_MEMBER)
: 로그인 시점에 세션에 보관한 회원 객체를 찾음 @GetMapping("/")
public String homeLoginV3Spring(
@SessionAttribute(name=SessionConst.LOGIN_MEMBER,required = false) Member loginMember,
Model model){
//세션에 회원 데이터가 없으면 home
if(loginMember==null){
return "home";
}
//세션이 유지되면 로그인으로 이동
model.addAttribute("member",loginMember);
return "loginHome";
}
@SessionAttribute
을 지원로그인을 처음 시도하면 URL이 jsessionid을 포함하고 있음
http://localhost:8080/;jsessionid=F59911518B921DF62D09F0DF8F83F872
URL 전달 방식을 끄고 항상 쿠키를 통해서만 세션을 유지하고 싶으면 옵션을 넣어줌
application.properties
server.servlet.session.tracking-modes=cookie
세션이 제공하는 데이터
session.getId()
: 세션ID, JSESSIONID의 값session.getMaxInactiveInterval()
: 세션의 유효 시간session.getCreationTime()
: 세션 생성일시session.getLastAccessedTime()
: 세션과 연결된 사용자가 최근에 서버에 접근한 시간, 클라이언트에서 서버로 sessionId (JSESSIONID)를 요청한 경우에 갱신session.isNew()
: 새로 생성된 세션인지의 여부세션의 종료 시점
스프링 부트로 글로벌 설정
application.properties
server.servlet.session.timeout=60
특정 세션 단위로 시간 설정
session.setMaxInactiveInterval(1800); //1800초
세션 타임아웃 발생
session.getLastAccessedTime()
(최근 세션 접근 시간) 이후로 timeout 시간이 지나면 세션이 제거됨session.getLastAccessedTime()
은 해당 세션과 관련된 JSESSIONID를 전달하는 HTTP 요청이 있으면 현재 시간으로 다시 초기화됨주의
세션에는 최소한의 데이터만 보관해야 함
예제에서는 멤버 객체를 담았으나, 실제로는 멤버의 아이디 정도만 담거나 최소한의 정보만 담는 것이 좋음