3 분 소요

 인프런 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술편을 학습하고 정리한 내용 입니다.

로그인 처리하기 - 서블릿 HTTP 세션1

세션이라는 개념은 대부분의 웹 애플리케이션에 필요한 것이다. 어쩌면 웹이 등장하면서 부터 나온 문제이다.

서블릿은 세션을 위해 HttpSession이라는 기능을 제공하는데, 지금까지 나온 문제들을 해결해준다.

우리가 직접 구현한 세션의 개념이 이미 구현되어 있고, 더 잘되어 있다.

HttpSession

서블릿이 제공하는 HttpSession도 결국 우리가 직접 만든 SessionManager와 같은 방식으로 동작한다.

서블릿을 통해 HttpSession을 생성하면 다음과 같은 쿠키를 생성한다. 쿠키 이름이 JSESSIONID이고, 값은 추정 불가능한 랜덤 값이다.

Cookie: JSESSIONID=5B78E23B513F50164D6FDD8C97B0AD05

HttpSession 사용하기

1
2
3
public class SessionConst {  
    public static final String LOGIN_MEMBER = "loginMember";  
}

HttpSession에 데이터를 보관하고 조회할 때, 같은 이름이 중복 되어 사용되므로, 상수를 하나 정의했다.

LoginContoller

이제 로그인, 로그아웃을 HttpSession을 사용하도록 하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 로그인 
@PostMapping("/login")  
public String loginV3(@Validated @ModelAttribute("loginForm") LoginForm form, BindingResult result, HttpServletRequest request) {  
  
    if (result.hasErrors()) {  
        return "login/loginForm";  
    }  
  
    Member loginMember = loginService.login(form.getLoginId(), form.getPassword());  
  
    if (loginMember == null) {  
        result.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:/";  
}

HomeController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@GetMapping("/")  
public String homeLoginV3(HttpServletRequest request, Model model) {  
  
    // 세션 관리자에 저장된 회원 정보 조회  
    // 세션을 지금 만들 이유가 없기 때문에 false    HttpSession session = request.getSession(false);  
  
    if (session == null) return "home";  
  
    Member loginMember = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);  
  
    // 세션에 회원 데이터가 없으면 그냥 홈  
    if (loginMember == null) return "home";  
  
    model.addAttribute("member", loginMember);  
    return "loginHome";  
}

로그인 하면 url에 세션이 붙어버리는데 때고 /로 접근하면 다음과 같이 잘 된다.

JSESSIONID로 저장되어 있는 걸 볼 수 있다.

세션 생성과 조회

세션을 생성하려면 request.getSession(true)를 사용하면 된다.

세션의 create 옵션에 대해 알아보자. defaulttrue이다.

  • request.getSession(true) (default)
    • 세션이 있으면 기존 세션을 반환한다.
    • 세션이 없으면 새로운 세션을 생성해서 반환한다.
  • request.getSession(false)
    • 세션이 있으면 기존 세션을 반환한다.
    • 세션이 없으면 새로운 생성하지 않는다. null을 반환한다.
  • request.getSession() == request.getSession(true)

  • session.invalidate() : 세션을 제거한다.
  • session.getAttribute(SessionConst.LOGIN_MEMBER) : 키 값으로 조회한다.

로그인 처리하기 - 서블릿 HTTP 세션 2

@SessionAttribute

스프링은 세션을 더 편리하게 사용할 수 있도록 @SessionAttribute를 지원한다.

이미 로그인 된 사용자를 찾을 때는 다음과 같이 사용하면 된다. (참고로 이 기능은 세션을 생성하지 않는다.)

HomeController - homeLoginV3Spring()

1
2
3
4
5
6
7
8
9
10
@GetMapping("/")  
public String homeLoginV3Spring(  
        @SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, Model model) {  
  
    // 세션에 회원 데이터가 없으면 그냥 홈  
    if (loginMember == null) return "home";  
  
    model.addAttribute("member", loginMember);  
    return "loginHome";  
}

세션에서 바로 Member 객체를 바인딩 했다. 있으면 로그인이고 아니면 비로그인으로 가는 너무 간단해진 코드이다.

일단 url에 다음과 같이 jsessionid=랜덤값 이 붙는 걸 볼 수 있다.

이거 때문에 404 에러가 나오는데, 저걸 제거하고 / 로 다시 접근하면

세션이 잘 들어가 있고, 로그인도 잘 처리 됐다.

TrackingModes에 대해 알아봐야 한다.

TrackingModes

로그인을 처음 시도하면 URL이 다음과 같이 jsessionid 를 포함하고 있는 것을 확인할 수 있다.

1
http://localhost:8080/;jsessionid=F59911518B921DF62D09F0DF8F83F872

이것은 웹 브라우저가 쿠키를 지원하지 않을 때 쿠키 대신에 URL을 통해서 세션을 유지하는 방법이다.

이 방법을 사용하려면 URL에 이 값을 계속 포함해서 전달해야 한다.

타임리프 같은 템플릿은 엔진을 통해서 링크를 걸면 jsessionid를 URL에 자동으로 포함해 준다.

서버 입장에서 웹 브라우저가 쿠키를 지원하지 않는지 최초에는 판단하지 못하므로, 쿠키 값도 전달하고, URL에 jsessionid도 함께 전달한다.

URL 전달 방식을 끄고 항상 쿠키를 통해서 세션을 유지하고 싶으면 다음 옵션을 넣어주면 된다.

이렇게 하면 URL에 jsessionid가 노출되지 않는다.

application.properties

1
server.servlet.session.tracking-modes=cookie

주의! jsessionid가 url에 있을때 404 오류가 발생한다면

스프링에서 최근 URL 매핑 전략이 변경됨.

따라서

1
http://localhost:8080/;jsessionid=F59911518B921DF62D09F0DF8F83F872

다음과 같이 접근한다면 404 오류가 발생할 수 있다.

그래서

application.properties

1
server.servlet.session.tracking-modes=cookie

session.tracking-modes 이 옵션을 사용하는 것을 권장한다.

만약에 URL에 jsessionid가 꼭 필요하다면 application.properties에 다음 옵션을 추가하자.

1
spring.mvc.pathmatch.matching-strategy=ant_path_matcher

댓글남기기