현재 프로젝트에서 로그인 방식으로 세션을 사용하고 있습니다.
쿠키의 경우 클라이언트의 리소스를 사용하기 때문에 서버의 부하가 적으나
웹 브라우저마다 지원 형태도 다르고 보안에 취약해서 사용하지 않았습니다.
세션을 사용하여 로컬 환경에서 프로젝트를 진행할 때,
수정사항이 생겨 애플리케이션을 재시작해야 하는 경우
세션이 만료되어 다시 로그인을 했어야 했습니다.
이는 세션이 기본적으로 톰캣 세션을 사용하기 때문입니다.
✅ 세션 저장소
세션은 쿠키와 다르게 서버의 리소스를 사용합니다.
때문에 세션을 만들면 서버에서 관리되는 것이죠.
이런 세션을 저장하는 저장소로 보통 3가지 방식이 사용됩니다.
☝ 톰캣 세션
- 따로 설정을 하지 않은 경우 기본적으로 톰캣에 세션이 저장됩니다.
- 앞서 말했듯이, 애플리케이션을 재구동 하는 경우 세션 정보가 만료됩니다.
- 제 프로젝트의 경우 하나의 EC2 서버를 사용하고 있지만,
서버가 여러 대인 경우, 혹은 서버의 Scale-Out을 염두에 두고 있는 경우
톰캣 세션을 사용하면 톰캣들 간 세션 공유를 위한 추가 설정이 필요합니다.
☝ DB 활용
- MySQL, Oracle과 같은 DB를 활용해 세션의 정보를 저장합니다.
- 세션의 정보가 DB에 저장되어 관리되기 때문에 서버가 여러 대여도 괜찮습니다.
- 애플리케이션이 재구동 돼도 세션 정보가 유지됩니다.
☝ Redis, Memcached 등
- In-Memory DB 방식을 말합니다.
- In-Memory DB는 컴퓨터의 주 메모리에 세션 정보를 저장하기 때문에
HDD나 SDD를 사용하는 저장소보다 빠른 속도로 세션 정보를 불러올 수 있습니다.
저는 상기한 3가지 방식 중 'DB 활용' 방식을 선택하여 사용하고 있습니다.
Redis와 같은 방식은 Scale-out 할 경우 별도의 Redis 서버를 구축해야 한다는 문제가 있었고,
현재 서비스는 많은 세션의 접근을 필요로 하지 않기 때문에
DB에 저장하는 방식으로도 서버에 부하 없이 이용이 가능해서 DB 활용 방식을 선택했습니다.
✅ DB를 세션 저장소로 사용하는 방법
☝ 우선 'Application.properties'를 설정해줍니다.
다음과 같은 코드를 Application.properties에 추가합니다.
# 세션 저장소 설정
spring.session.store-type=jdbc
☝ Spring Session JDBC의 의존성 주입이 필요합니다.
저는 Gradle 프로젝트이기 때문에 다음과 같은 코드를 'build.gradle'에 추가해줬습니다.
//세션 저장
implementation 'org.springframework.session:spring-session-jdbc:2.7.0'
☝ 활용 중인 DB에 테이블을 추가해줍니다.
현재 저는 'MySQL'을 사용하고 있습니다.
다음과 같은 SQL문을 차례로 실행해줍니다.
CREATE TABLE SPRING_SESSION (
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
EXPIRY_TIME BIGINT NOT NULL,
PRINCIPAL_NAME VARCHAR(100),
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);
CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES MEDIUMBLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);
이제 만들어진 테이블을 조회해보겠습니다.
다음과 같이 'SPRING_SESSION' 테이블을 조회하면 아무런 결과도 나오지 않습니다.
관리되는 세션이 없다는 것으로 현재 프로젝트에서 어떤 세션도 만들지 않았기 때문입니다.
로그인을 해서 세션을 생성하고 테이블을 다시 조회해보겠습니다.
위와 같이 생성된 세션을 DB로 조회할 수 있습니다.
세션에 보안 문제가 발생하거나 부적절하게 생긴 세션은 DB에서 강제적으로 만료시킬 수 있습니다.
'내가 공부하려고 올리는 > 스프링' 카테고리의 다른 글
스프링 인터셉터(Interceptor) (0) | 2022.07.13 |
---|---|
PathVariable, RequestParam, RequestBody(스프링에서 파라미터 받기) (0) | 2022.07.12 |
프로젝트를 더욱 S.O.L.I.D 하게 수정해보기 (0) | 2022.07.12 |
나는 ServiceImpl을 잘 활용했는가? (0) | 2022.07.11 |
스프링 MVC와 계층형 아키텍처(Layered Architecture) (0) | 2022.07.11 |
댓글