[Spring] Session

Manx·2022년 6월 4일
0

spring

목록 보기
15/24

인프런 스프링 MVC 2편 - 김영한 강사님의 강의 내용입니다.



쿠키를 통해 로그인 상태를 유지하면 심각한 보안 문제가 발생하기 때문에 session을 이용해서 로그인 처리를 할 수 있다.

Session이란?

서버가 클라이언트에 seesionID만 쿠키에 담아 전달하고, 서버에서는 sessionID에 해당하는 정보들을 저장한다.

  • 쿠키 값 변조 -> 예측 불가능한 복잡한 세션ID 사용
  • 쿠키에 보관하는 정보 탈취 : 세션ID가 노출되어도 여기에는 중요한 정보가 없음
  • 쿠키 탈취 후 사용 : 서버에서 세션의 만료시간을 짧게 유지

서블릿에서 세션을 제공해 주지만, 강의에서 세션을 한번 직접 만들어 보았다.

1. 세션 생성

UUID를 통해 중복될 가능성이 없는 ID를 생성한 후 Cookie의 sessionID로 설정한다.

public void createSession(Object value, HttpServletResponse response) {

        // 세션 id를 생성하고, 값을 세션에 저장
        String sessionId = UUID.randomUUID().toString();
        sessionStore.put(sessionId, value);

        //쿠키 생성
        Cookie mySessionCooke = new Cookie(SESSION_COOKIE_NAME, sessionId);
        response.addCookie(mySessionCooke);
    }

2. 세션 조회

만약 쿠키의 값이 없다면 null을 반환하고, 쿠키에 값이 있다면 해당하는 쿠키의 값을 조회해 반환한다.

public Object getSession(HttpServletRequest request) {
    Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
    if (sessionCookie == null) {
        return null;
    }
    return sessionStore.get(sessionCookie.getValue());
}

public Cookie findCookie(HttpServletRequest request, String cookieName) {
    if (request.getCookies() == null) {
        return null;
    }
    return Arrays.stream(request.getCookies())
            .filter(cookie -> cookie.getName().equals(cookieName))
            .findAny()
            .orElse(null);
}

3. 세션 만료

쿠키를 찾아 삭제한다.

public void expire(HttpServletRequest request) {
    Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
    if (sessionCookie != null) {
        sessionStore.remove(sessionCookie.getValue());
    }
}

TestCode

TestCode에서 HttpServletResponse를 사용할 수 없으므로 MockHttpServletResponse를 사용하면 된다고 한다. 이에 대해서는 나중에 더 자세히 알아보겠다.

class SessionManagerTest {

    SessionManager sessionManager = new SessionManager();

    @Test
    void sessionTest() {

        //세션 생성
        MockHttpServletResponse response = new MockHttpServletResponse();
        Member member = new Member();
        sessionManager.createSession(member, response);

        //요청에 응답 쿠키 저장
        MockHttpServletRequest request = new MockHttpServletRequest();
        request.setCookies(response.getCookies());

        //세션 조회
        Object result = sessionManager.getSession(request);
        Assertions.assertThat(result).isEqualTo(member);

        //세션 만료
        sessionManager.expire(request);
        Object expired = sessionManager.getSession(request);
        Assertions.assertThat(expired).isEqualTo(null);
    }
}

서블릿이 제공하는 세션 (HttpSession)

세션 생성

public HttpSession getSession(boolean create);

request.getSession(true) => Default

  • 세션이 있으면 기존 세션 반환
  • 세션이 없을 경우 새로운 세션을 생성해 반환

request.getSession(false)

  • 세션이 있으면 기존 세션을 반환
  • 세션이 없으면 새로운 세션을 생성하지 않고 null 반환

세션에 값 보관

public void setAttribute(String name, Object value);

세션 제거

public void invalidate();

스프링을 통한 세션 사용

@SessiongAttribute 어노테이션을 이용해 세션을 편리하게 사용할 수 있다.

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

브라우저에서 쿠키를 지원하지 않을 수 있기 때문에 다음과 같이 URL에 jsession을 포함해 지원한다.

  • localhost:8080/;jsessionid=F59911518B921DF62D09F0DF8F83F872

URL 전달 방식을 끄고 항상 쿠키를 통해서만 세션을 유지하고 싶다면
application.properties에 server.servlet.session.tracking-modes=cookie 옵션을 넣어주면 된다.

profile
백엔드 개발자

0개의 댓글