[Spring] Login Cookie&Session

유존돌돌이·2022년 4월 5일
0

Spring

목록 보기
20/26

1. 쿠키 생성 및 HttpServletResponse에 등록

Cookie idCookie = new Cookie("memberId", String.valueOf(loginMember.getId()));
response.addCookie(idCookie);

2. 쿠키 전달

@GetMapping("/")
public String homeLogin(@CookieValue(name="memberId", required = false) Long memberId, Model model) {..

위 경우는 정상 로그인이 된다면 / 화면으로 돌아가는것
여기서 required = false는 최초 로그인하지 않는 경우(쿠키값이 없는경우)도 있기 때문에 false로 한다.

3. 쿠키 삭제(로그아웃)

Cookie cookie = new Cookie("memberId", null);
cookie.setMaxAge(0);
response.addCookie(cookie);

당연히 중요정보를 쿠키를 사용하면 절대 절대 안된다!

2. Session

  1. 회원과 관련된 정보는 전혀 클라이언트에 전달하지 않는다는 것
  2. 오직 추정 불가능한 세션 ID만 쿠키를 통해 클라이언트에 전달

세션처리 직접 만들기(MAP)

  1. SessionManager
@Component
public class SessionManager {

    private Map<String, Object> sessionStore = new ConcurrentHashMap<>();
    public static final String SESSION_COOKIE_NAME = "mySessionId";

    /**
     * 세션 셜정
     * * SessionId 생성 (임의의 추정 불가능한 랜덤 값)
     * * 세션 저장소에 sessionId와 보관할 값 저장
     * * sessionId로 응답 쿠키를 생성해서 클라이언트에 전달
     */
    public void createSession(Object value, HttpServletResponse response) {

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

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

    /**
     * 세션 조회
     */
    public Object getSession(HttpServletRequest request) {
        Cookie sessionCookie = findCookie(request);
        if(sessionCookie==null) {
            return null;
        }
        return sessionStore.get(sessionCookie.getValue());
    }

    /**
     * 세션 만료
     */
    public void expire(HttpServletRequest request) {
        Cookie sessionCookie = findCookie(request);
        if(sessionCookie!=null) {
            sessionStore.remove(sessionCookie.getValue());
        }
    }

    public Cookie findCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if(cookies==null) return null;

        return Arrays.stream(cookies)
                .filter(c -> c.getName().equals(SESSION_COOKIE_NAME))
                .findFirst()
                .orElse(null);
    }

}
  1. SessionManagerTest
class SessionManagerTest {

    SessionManager sessionManager = new SessionManager();

    @Test
    void sessionTest() {
        //세션생성
        Member member = new Member();
        MockHttpServletResponse response = new MockHttpServletResponse();
        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);
        Assertions.assertThat(sessionManager.getSession(request)).isNull();
    }
}

-> HttpRequestServlet, HttpResponseServlet은 인터페이스가 아니기 때문에 테스트하려면 Mock(가짜객체)를 사용한다.

HttpSession 사용

1. 로그인

// 로그인 성공 처리 TODO
// 세션이 있으면 있는 세션 반환, 없으면 신규 세션을 생성
HttpSession session = request.getSession();
// 세션에 로그인 회원 정보 보관
session.setAttribute(SessionConst.LOGIN_MEMEBER, loginMember);

2.로그아웃

// false로 해야 세션이 없을때 자동으로 생성하지 않는다.
HttpSession session = request.getSession(false);
if(session!=null) {
	// 세션초기화
	session.invalidate();
}

3. 로그인 후 세션 처리 Session Attribute

@GetMapping("/")
    public String homeLoginV3(@SessionAttribute(name=SessionConst.LOGIN_MEMEBER, required = false) Member member, Model model) {

        // 세션에 회원 정보가 없다면 기본 홈
        if(member==null) {
            return "home";
        }

        //로그인
        model.addAttribute("member", member);
        return "loginHome";
    }

@SessionAttribute(name=SessionConst.LOGIN_MEMEBER, required = false) 라는 Argument로 세션의 이름과 require(여기서는 메인화면이기 때문에 세션이 없는 경우가 있어서 false)로 세션정보를 바로 받아올 수 있다.

참고로 로그인을 처음 시도하면 URL이 다음과 같이 jsessionid를 포함하고 있는 것을 확인할 수 있다.
따라서 application.properties에 아래 세팅값을 추가한다.

server.servlet.session.tracking-modes=cookie : 쿠키로 트래킹 모드
server.servlet.session.timeout=1800 : 세션유지시간

0개의 댓글