qkrtkdwns3410

Spring Session

Spring Session
14 days ago
·
9 min read

Spring Session

  • 사용자 세션 정보 관리를 위한 API 와 구현체 제공

  • 어플리케이션 컨테이너에 종속되지 않고 클러스터링 된 세션 지원

HttpSession

WebSocket

WebSession

크게 3가지의 구현체를 제공한다.

왜 클러스터링된 세션이 필요한지

  • 일반적으로 세션은 각 서버 메모리에 저장.

  • 분산 환경에서는

    • 서버 #1 세션이

    • 서버 #2 로 가는 경우 세션이 사라져버린다.

해결방안

  • 공유 저장소로 세션 관리

    • 공유 세션 저장소(Shared Session Storage) 도입 필

    • 모든 서버가 같은 저장소 (Redis, DB 등) 을 바라봄

    • 서버 #2 에서 세션 데이터를 요청해도 문제없음.

어떤식으로 해결하는건지?

  • 스프링 세션

    • 어플리케이션과 세션 관리 사이에 추상화 계층 생성.

    • 이를 통해 다양한 저장소(RDB, NoSQL, Redis 등) 저장이 가능

언제 쓰나

  1. 분산 웹 어플리케이션 ~ MSA 서버

  2. 확장성 문제 해결

    1. 동시 사용자가 많은 대형 어플리케이션에서 서버 메모리에 세션 저장하면 한계가 있음

    2. 별도의 세션 저장소가 필요하다

  3. 백업 + 복구

Spring Session Modules

  1. spring-session 레포지터리

    1. 코어 모듈

    2. 몽고 DB 모듈

    3. 레디스 모듈

    4. JDBC 모듈

    5. Hazelcast 모듈

      1. 자바 오픈소스 인메모리 데이터 그리드

    이 있음.

  2. spring-session-data-geode 페포지터리

  3. spring-session-bom 레포지터리

Spring Session + HttpSession

HttpSession

  • 손님의 주문 정보를 담은 하나의 노트라고 보면 된다.

  • 단일 어플리케이션의 경우

    • 해당 추상체를 사용해도 문제없지만

  • 매장마다 고유의 주문 정보를 담아서 사용하기는 불가능하다.

    • 다른 매장에 주문정보를 담아서 간다고 하더라도

    • 해당 매장에서는 그 주문정보와 양식이 달라 종업원이 처리하기가 힘들어진다.

  • 그래서 등장한 것이

Spring Session 인데

  • 어디로 가든지 주문 정보가 공유되는 시스템을 손쉽게 구축이 가능해진다.

Spring Session 의 장점

  • 클러스터링을 지원

    • 노트대신 클라우드 시스템으로 메모 내용이 공유된다고 생각하면 된다

  • RESTful 지원

    • 헤더에 세션 ID 를 넣어서 관리가 가능해진다.

    • 원래 단일 어플리케이션의 경우 JSESSION - 쿠키로 관리하는게

    • MSA 구조에서는 API 헤더를 통해 정보가 오가게 된다.

Redis 와 연동

@EnableRedisHttpSession 
public class Config {

	@Bean
	public LettuceConnectionFactory connectionFactory() {
		return new LettuceConnectionFactory(); 
	}

}

  • @EnableRedisHttpSession 같은 경우

    • 레디스를 공유 세션 저장소로 사용할 것입니다!

    • 의 선언이다

  • LettuceConnectionFactory 의 경우

    • Redis 에 연결하는 코드로서

    • local:6379 로 정의되어 있는 경우 해당 포트에 연결을 시도한다

    • 만약 별도의 세션 저장소 url 이 있다면 해당 위치에 저장을 시도하면 된다.

Spring Configuration 이 추가적으로 해줘야하는 일이 있음.

  • tomcat 의 경우 기본적으로 HTTP SESSION 을 사용하려고하기에

    • 별도로 Spring Session 을 사용하도록 명령을 내려줘야한다.

  • springSessionRepositoryFilter 으로 해당 명령을 내릴 수 있는데

    • 모든 요청(Request) 에 대해 HttpSession 을 새롭게 SpringSession 으로 변경한다.

  • 여기서 등장하는 개념이 Initializer 이다.

    public class Initializer extends AbstractHttpSessionApplicationInitializer { 
    	public Initializer() {
    		super(Config.class); 
    	}
    }
    
    • AbstractHttpSessionApplicationInitializer 을 상속받음으로서

      • Tomcat 에게 Config.class 를 사용해서 springSessionRepositoryFilter 를 만들라고 지시를 한다.

      • 해당 필터생성 후 → 모든 HTTP 요청이 필터를 거쳐서 HttpSession → Spring Session 으로 변경된다.

Spring Security + Spring Session

  • spring session 에서 는 spring security 에 있는 rememberMe 관리가 가능함.

기존 spring security 관련

  1. 쿠키 기반으로 동작한다.

    1. 쿠키에 나는 누구야~ 라고 정보를 저장하고

    2. 쿠키를 브라우저에서만 저장됨.

  2. 서버에서는 추적이 안된다

    1. 쿠키가 유효하면 통과시키고 로그인하라고하면 한다..

문제점

  • 클러스터된 서버의 경우 쿠키를 공유하지 못하여 remember-me 기능이 사용이 되지 않는다.

Spring Session 기반 Spring Security

  1. 서버 측 데이터 관리

    1. remember-me 정보를 레디스 같은 인메모리에 저장함.

    2. 모든 서버에서 세션 데이터를 동일한 환경에서 사용이 가능하다

  2. 유연한 쿠키 관리가 가능

    요 내용은 일반 Spring Security 에서도 가능하지 않나 생각됨..

    왜 굳이 스프링 공식문서에 추가되어 있는지는 모르겠음.

    1. Spring Session Remember-me 기능은 쿠키 만료가 INTEGER.MAX_VALUE 로 설정한다고 한다.

    2. 쿠키의 유효기간이 무한대

    3. 세션 갱신 문제 해결 가능

      세션 갱신 문제?

      • 사용자가 로그인한 상태에서 세션 갱신되는 경우

      • 서버는 새로운 세션데이터를 만든다.

      • 쿠키의 유효기간은 갱신되지 않아

        • 사용자가 다시 로그인을 해야하는 문제가 있음.

User Concurrent Session Control

동시 접속 방지 기능

  • 한 브라우저에서 로그인 + 다른 브라우저에서 또 로그인한 경우

  • 해당 동시접속 세션에 대해 제어가 가능하다.

GPT 코드 예시

@Configuration
public class SecurityConfiguration<S extends Session> extends WebSecurityConfigurerAdapter {

	@Autowired
	private FindByIndexNameSessionRepository<S> sessionRepository;

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
			// 추가 설정...
			.sessionManagement((sessionManagement) -> sessionManagement
				.maximumSessions(2)  // 최대 2개의 세션만 허용
				.sessionRegistry(sessionRegistry())
			);
	}

	@Bean
	public SpringSessionBackedSessionRegistry<S> sessionRegistry() {
		return new SpringSessionBackedSessionRegistry<>(this.sessionRepository);
	}
}
  1. 세션 제한 설정

    • maximumSessions 을 통하여 동시에 가질 수 있는 세션을 2개로 제한..

  2. 세션 클러스터링을 지원

    1. SpringSessionBackedSessionRegistry 을 사용해 여러 서버(클러스터) 환경에서도 해당 규칙이 적용

    2. 다른 서버에서 호출이 되더라도, 사용자가 이미 2개의 세션을 가지고 있는지 여부를 확인이 가능해짐.

    어떻게 확인하는걸까?

    • 레디스 같은 경우

      keys spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:<username>*
      
      • 이런식으로 특정 키 값에 세션이 어떤 사용자와 연결되어 있는지 확인함.

      • 사용자가 2개의 세션을 활성화한 경우 키가 2개가 나오게 된다.







새는 알에서 빠져나오려고 몸부림친다. 알은 세계다. 태어나려고 하는 자는 하나의 세계를 파괴하지 않으면 안 된다. 그 새는 신을 향해 날아간다