로그인 처리 -2 (HttpSession)

나무·2023년 11월 19일

스프링 MVC

목록 보기
8/12
post-thumbnail

앞선 시간에선 쿠키와 세션에 관해 이론적인 개념을 살펴보았다. 우린 해당 개념을 통해 직접 세션 저장소를 구현 할 수도 있다.

하지만 늘 그렇듯 이미 스프링에는 모든것이 준비 되어있고 세션 또한 마찬가지이다. 직접 구현 하는것도 공부하는데 있어서는 좋지만 사용할 땐 웬만하면 프레임워크가 제공하는 것을 사용하자.(바퀴는 다시만드는게 아니다,,!)

0. 로그인 요구사항

로그인에 성공할 경우 홈 화면으로 이동을 하는데 이때 로그인 된 회원의 경우 홈 화면에 사용자의 아이디가 출력돼야한다.

그리고 비로그인 상태일때는 그냥 홈화면이 출력된다.

1. HttpSession 사용 - 로그인

Controller : login()

	@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:/";

    }

request.getSession()

클라이언트의 요청 메시지의 쿠키에서 세션ID 를 꺼낸다음 세션저장소에서 세션객체를 꺼냄.

만약 세션이 없다면 세션객체를 새로 생성하는데 파라미터에 false 를 넣으면 새로 생성해주지 않는다. (기본값은 true)

session.setAttribute(키, 값)

세션 저장소로부터 꺼내온 세션에 회원정보를 집어어넣어주는데 이 또한 key-value 형태로 되어있다.
key -> SessionConst.LOGIN_MEMBER
value -> loginMember

Controller : homeLogin()

    @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()

개발자가 직접 HttpServletRequest 에서 세션ID 를 추출해서 세션 객체를 만들고 세션에서 해당 회원 멤버 객체를 저장하는 과정을 구현할 필요가없다.

그냥 어노테이션만 등록해주면 알아서 loginMember 에 세션ID 에 맞는 멤버객체를 집어넣어준다.

  • 세션이 없다면 -> 비로그인 홈 화면을 반환하고

  • 세션이 있다면 ->
    - 회원정보가 없다면 -> 비로그인 홈 화면 을 반환하고
    - 회원정보가 있다면 -> 로그인 홈 화면 을 반환한다.

2. HttpSession 사용 - 로그아웃

Controller

	@PostMapping("/logout")
    public String logoutV3(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }
        return "redirect:/";
    }

HttpSession session = request.getSession(false);

로그아웃의 경우 세션저장소에서 세션을 삭제하는 과정이다. 때문에 세션이 없다고 해서 새로 생성을 하면 안된다. 그래서 파라미터에 false 를 집어 넣는다.

session.invalidate();

해당 세션을 파기해버린다.

3. 세션 자동 파기

로그아웃을 누르면 세션저장소에 해당 세션을 제거해버린다. 그런데 많은 사람들이 로그아웃을 잘 누르지 않고 그냥 브라우저를 닫아버린다.

문제는 서버의 경우 로그아웃 요청이 들어오지 않으면 유저가 계속 웹사이트를 사용하고 있는지 없는지 판단 할 수가 없다. 즉, 로그아웃을 누르지 않으면 영원히 세션 저장소에 세션이 남아있는다.

이렇게 되면 자칫 해커가 사용자들의 쿠키를 탈취해 세션ID 를 확보한다음 해당 ID로 로그인을 할 수 있다는 뜻이다. 그래서 너무 오랫동안 세션저장소에 세션이 남아있게 해서는 안된다.

타임아웃 설정

서버는 사용자의 접속상태를 모르기 때문에 사용자의 최종 request를 기준으로 특정시간을 정해놓고 시간이 지나면 세션을 파기 하는 방식을 사용할 수 있다.

대신 요청이 들어오면 타임아웃 시간도 다시 갱신된다.

application.properties

위와 같은 세션의 타임아웃 설정은 application.properties 에서 다음과 같이 등록해주면 된다.

#server.servlet.session.timeout=1800

숫자의 단위는 이며 기본적으로 30분으로 맞춰놓는다. 하지만 타임아웃은 웹사이트의 정책에 따라 달라질 수 있으며 너무 짧으면 사용성이 떨어질 수 있다.

반대로 너무 길면 보안이 취약해지며 또한 세션은 서버의 메모리를 사용하기 때문에 사용자 수가 많은 경우 보관 시간이 길어질 수록 서버에 부담이 될 수 있다.

본 포스트는
김영한의 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 강의 를 보고 정리했습니다.

profile
🍀 개발을 통해 지속 가능한 미래를 만드는데 기여하고 싶습니다 🍀

0개의 댓글