세션 ( Session )
세션은 사용자가 웹 브라우저를 통해 웹 서버에 접속한 시점부터 브라우저를 종료하여 연결을 끊을 때 까지의 일련의 과정을 의미합니다.
세션을 통해 웹 서버는 각각의 사용자 정보를 일정 시간 동안 유지할 수 있습니다.
주요 특징
- 네트워크 상에서 두 개 이상의 통신 장치간에 유지되는 상호 연결을 의미
- 연결된 일정 시간 동안 유지되는 정보를 나타냄
- 적용 대상에 따라 다른 의미를 가짐
- 사용자 식별 : 웹은 기본적적으로 상태가 없는 (stateless) 프로토콜 입니다. 즉, 두 개의 페이지 요청 사이에 사용자 정보가 저장되지 않습니다. 세션을 사용하면 사용자마다 고유한 세션ID를 부여하고 사용자를 식별 및 그에 따른 정보를 저장할 수 있습니다.
- 데이터 저장 : 사용자의 정보, 로그인 상태, 장바구니 내용 등을 일정 시간 동안 유지하고 싶을 때 세션을 사용하여 이러한 데이터를 저장할 수 있습니다.
- 보안 : 쿠키와 달리 세션 데이터는 서버측에 저장되므로 사용자가 직접 접근하거나 수정하기 어렵습니다. 따라서 로그인 정보와 같은 민감한 데이터를 저장할 때 세션을 사용하면 보안성이 높아집니다.
- 시간 제한 : 세션에는 일정 시간의 유효기간이 있습니다. 이 시간 동안 사용자가 서버에 새로운 요청을 하지 않으면 세션은 자동으로 만료 됩니다.
작동 방식
- 사용자기 웹 사이트에 처음 접속하면 서버는 고유한 세션 ID를 생성합니다.
- 세션ID 는 추정 불가능하며, 중복 되지 않는다. -> 예상 불가능한 복잡한 세션ID를 사용합니다.
- 생성된 세션ID는 쿠키를 통해 사용자의 브라우저에 전달 됩니다.
- 클라이언트는 요청시 항상 세션ID 쿠키를 전달 합니다.
- 사용자가 웹 사이트 내에서 다른 페이지로 이동하거나 데이터를 요청할 때마다 세션 ID가 서버에 전달 됩니다.
- 서버는 세션ID를 기반으로 해당 사용자의 세션 데이터를 찾아 사용합니다.
- 서버에서는 클라이언트가 전달한 세션ID 정보로 세션 저장소를 조회해서 로그인시 보관한 세션 정보를 사용합니다.
- 사용자가 로그아웃 하거나 일정 시간 동안 활동이 없으면 세션은 만료 됩니다.
세션 작동 방식
분산 환경에서의 세션 처리
- 서버는 세션 정보를 저장해야 합니다.
- 서버가 여러 대라면 최초 로그인한 서버가 아닌 서버는 세션 정보를 알지 못합니다.
- 세션 정보를 서버간에 공유할 방법이 필요 (세션 클러스터링)
- 요즘 서버는 스케일 아웃이 일반적 입니다
분산 환경
RDB 사용
- 관계형 데이터 모델이 필요한가?
- 영속성이 필요한 데이터인가?
- 성능 요구사항을 충족하는가?
- RDB를 사용하면 어느정도 요구사항은 충족 될 수 있지만, 서버에 접속할 때마다 DB를 조회하여 유저 정보를 확인해야 하는 단점이 있다.
DB를 사용한 방법
REDIS 사용
- 세션 데이터는 단순 key-value 구조
- 세션 데이터는 영속성이 필요 없음
- 세션 데이터는 변경이 빈번하고 빠른 액세스 속도가 필요
Redis를 활용한 세션 클러스터링
Springboot + Redis를 사용한 세션클러스터링
아래 의존성을 추가합니다.
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.session:spring-session-data-redis'
application.yml 파일에 아래 내용을 추가합니다.
redis:
host: 127.0.0.1
port: 6379
password:
lettuce:
pool:
max-active: 10
max-idle: 8
min-idle: 2
session:
store-type: redis
redis:
namespace: spring:session:redis
flush-mode: on_save
server:
servlet:
session:
cookie:
name: mysessionId # 쿠키 이름을 선택적으로 설정합니다.
domain: .application.com # 주요 도메인 앞에 '.'를 사용하여 서브도메인 간의 쿠키를 공유하게 합니다.
path: / # 쿠키의 경로. 일반적으로 루트로 설정됩니다.
secure: false # HTTPS를 사용하는 경우에만 쿠키를 전송하려면 이 값을 'true'로 설정
http-only: true # JavaScript에서 쿠키에 액세스할 수 없도록 설정합니다. 권장됩니다.
RedisConfig.java
@Configuration
@EnableRedisHttpSession(redisNamespace = "${spring.session.redis.namespace}")
public class RedisConfig {
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
ObjectMapper om = new ObjectMapper();
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
// 서버의 메모리가 아니라 , Redis에 저장된 세션 정보를 사용 한다.
@Bean
public SpringSessionBackedSessionRegistry<? extends Session> sessionRegistry() {
return new SpringSessionBackedSessionRegistry<>(this.sessionRepository);
}
}
/*
아래 코드는 SpringSession에서 HTTP 쿠키릴 직렬화 역직렬화 하는 역활을 합니다.
SpringSession에서는 세션 정보를 쿠키를 통해 클라이언트에게 전송하고, 이후 요청에서 해당 쿠키를 다시
받아와서 사용자의 사용자의 세션을 식별화 합니다.
*/
@Configuration
public class CookieConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
// application.com 및 하위 도메인에서 쿠키를 공유하도록 설정
serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
return serializer;
}
}
위와 같이 설정하게 되면 기본적으로 application.com 도메인을 가진 세션은 공유되게 됩니다. SpringSecurity의 경우 자동으로 세션정보가 redis에 저장되게 됩니다.
테스트 방법은 x.application.com:8080 , v.application.com:8081 두개를 띄우고 세션이 공유되는지 확인 합니다.
'Redis' 카테고리의 다른 글
Redis 리더보드 만들기 (0) | 2023.12.11 |
---|---|
서비스 속도를 높이는 캐시 레이어 (0) | 2023.12.11 |
Redis 설치 및 문법 (1) | 2023.12.11 |
RDBMS & NoSQL & Redis (0) | 2023.12.11 |
Redis 소개와 특징 (0) | 2023.12.11 |