BE/Spring
스프링 MVC 2 - 로그인 처리 세션 직접 구현
오봉봉이
2022. 8. 29. 00:58
728x90
로그인 처리 - 세션 직접 만들기
세션을 직접 개발해서 사용해보자.
세션 관리는 크게 3가지 기능을 제공하면 된다
- 세션 생성
- sessionId 생성(임의의 추정 불가능한 랜덤 값)
- 세션 저장소에 sessionId와 보관할 값 저장
- sessionId로 응답 쿠키를 생성해서 클라이언트에 전달
- 세션 조회
- 클라이언트가 요청한 sessionId 쿠키의 값으로 세션 저장소에 보관한 값 조회
- 세션 만료
- 클라이언트가 요청한 sessionId 쿠키의 값으로 세션 저장소에 보관한 sessionId와 값 제거
SessionManager - 세션 관리
@Component
public class SessionManager {
private static final String SESSION_COOKIE_NAME = "mySessionId";
private Map<String, Object> sessionStore = new ConcurrentHashMap<>();
// 세션 생성
public void createSession(Object value, HttpServletResponse response) {
// 세션 id를 생성하고, 값을 세션에 저장
String sessionId = UUID.randomUUID().toString();
sessionStore.put(sessionId, value);
Cookie mySessionCookie = new Cookie(SESSION_COOKIE_NAME, sessionId);
response.addCookie(mySessionCookie);
}
// 세션 조회
public Object getSession(HttpServletRequest request) {
// Cookie[] cookies = request.getCookies();
//
// for (Cookie cookie : cookies) {
// if (cookie.getName().equals(SESSION_COOKIE_NAME)) {
// return sessionStore.get(cookie.getValue());
// }
// }
// 위 코드를 아래 코드로 변환 가능
Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
if (sessionCookie == null) {
return null;
}
return sessionStore.get(sessionCookie.getValue());
}
// 세션 만료
public void expire(HttpServletRequest request) {
Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME);
if (sessionCookie != null) {
sessionStore.remove(sessionCookie.getValue());
}
}
private Cookie findCookie(HttpServletRequest request, String cookieName) {
if (request.getCookies() == null) {
return null;
}
// request.getCookie()의 반환 값은 Array임
return Arrays.stream(request.getCookies()) // Array를 Stream으로 바꿔준다.
.filter(cookie -> cookie.getName().equals(cookieName)) // filter를 통해 파라미터 cookieName과 같은 것을 찾아냄
.findAny() // 같은 것들 중 처음 검색되는 하나만 반환, 검색되는 것들 중에서 첫 번째에 있는 findFirst()를 사용해도 된다.
.orElse(null); // 검색되는 것이 없으면 Null 반환
}
}
- @Component : 스프링 빈으로 자동 등록
- ConcurrentHashMap : HashMap은 동시 요청에 안전하지 않기 때문에 동시요청에 안전한 ConcurrentHashMap 사용
SessionManagerTest - 테스트
class SessionManagerTest {
SessionManager sessionManager = new SessionManager();
@Test
void sessionTest() {
// 세션 생성
// HttpServletResponse, HttpServletRequest는 인터페이스다.
// 톰캣같은 WAS가 별도로 제공하기 때문에 스프링에서는 테스트을 위해 Mock 객체를 제공한다.
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);
assertThat(result).isEqualTo(member);
// 세션 만료
sessionManager.expire(request);
Object expired = sessionManager.getSession(request);
assertThat(expired).isNull();
}
}
HttpServletRequest
, HttpservletResponse
객체를 직접 사용할 수 없기 때문에 테스트에서 비슷한 역할을 해주는 가짜 MockHttpServletRequest
, MockHttpServletResponse
를 사용했다.
출처 : 인프런 김영한 지식공유자님 강의 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
728x90