Cookie와 Session

wangjh789·2022년 8월 9일
0

[Spring] 스프링-mvc-2

목록 보기
5/11
  • 영속쿠키 : 만료 날짜가 입력되면 해당 날짜까지 유지
  • 세션쿠키 : 만료 날짜를 생략하면 브라우저 종료시 까지 유지

Cookie를 이용한 로그인 방식

	@PostMapping("/login")
    public String login(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response) {
        if (bindingResult.hasErrors()) return "login/loginForm";

        Member loginMember = loginService.login(form.getLoginId(), form.getPassword());

        if (loginMember == null) {
            bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
            return "login/loginForm";
        }

        //로그인 성공 처리
        Cookie idCookie = new Cookie("memberId", String.valueOf(loginMember.getId()));
        response.addCookie(idCookie);
        return "redirect:/";
    }

    @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);
    }

로그인 성공하면 웹브라우저 쿠키에 memberId=<MEMBERID>를 설정한다.
로그아웃 시 memberId의 maxAge를 0으로 설정해 삭제한다.
위의 방식으로 로그인을 구현하면 악의적인 사용자가 브라우저의 쿠키를 조작해 다른 유저의 정보에 접근할 수 있다는 심각한 문제가 있다.

해결방안

  • 쿠키에 중요한 값을 노출시키지 않고, 사용자 별로 예측 불가능한 임의의 토큰을 노출하고, 서버에서 토근과 사용자 id를 매핑해서 인식한다. (토큰은 서버가 관리)
  • 해커가 토큰을 가져가도 시간이 지나면 사용할 수 없도록 서버에서 해당 토큰의 만료시간을 짧게 유지하고, 해킹이 의심되는 경우 서버에서 해당 토큰을 강제로 제거한다.

Session

세션 : 서버에 중요한 정보를 보관한고 연결을 유지하는 방법을 세션이라 한다.
서버는 서버 상에 위치한 세션 저장소에서 세션을 관리한다.

    @PostMapping("/login")
    public String loginV3(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletRequest request) {
        if (bindingResult.hasErrors()) return "login/loginForm";

        Member loginMember = loginService.login(form.getLoginId(), form.getPassword());

        if (loginMember == null) {
            bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다.");
            return "login/loginForm";
        }
        //로그인 성공 처리
        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:/";
    }

로그인이 성공하면 member를 조회해 세션에 넣는다.
로그아웃 시 세션을 가져와 invalid로 만든다.

request.getSession()
default가 create=true, 이 경우 세션이 존재하지 않는 경우 새로 생성된다.
create=false 인 경우, 세션이 존재하지 않으면 null을 반환한다.

session timeout

로그아웃을 하고 사이트를 나가는 사용자는 많이 없다. 대부분의 사용자들은 그냥 브라우저를 종료하거나 사이트를 나간다. 이럴 경우 서버는 사용자가 웹 사이트를 나갔는지 알지 못하기 때문에 세션을 계속 유지하면 세션 저장소는 점점 거대해진다.
이를 방지하기 위해서 세션에 마지막 접근 시간과 maxInactiveInterval을 이용해 일정 시간동안 접근하지 않은 세션을 삭제하는 식으로 세션을 관리한다.

profile
기록

0개의 댓글