[Redis] session로그인 어떻게 단점을 보안할거야?

Sol's·2023년 2월 2일
0

팀프로젝트

목록 보기
15/25

앞서 Oauth 로그인을 했을때 Session에 jwt를 저장하여 로그인을 구현했습니다.

그런데, 아래와 같은 아쉬운 부분이 있었습니다.

  1. 세션은 스케일 아웃시 공유되지 않는다.
  2. 서버에 저장되어있는 in-Memory에 접근해야하기때문에 트래픽이 몰린다면 서버가 복구될 때까지 서비스를 중단해야 하는 상황이 발생합니다.

스케일 업, 스케일 아웃이 궁금하다면?

사용자들이 서비스를 이용하다 위와같은 문제가 발생하여 다시 로그인을 하거나, 요청에대한 응답이 길어진다면 사용자 경험이 떨어져 다른서비스를 이용하거나, 서비스를 이용하지 않을 수 있습니다.

그러기 위해서는 스케일 아웃을 고려하여 서버를 확장해야합니다.
하지만 세션은 was 안에있는 프로젝트(각 서버의 램공간)에 생성이 되기때문에 서버가 분산이 된다면 사용자는 로그인을 다시 해야하는 상황이 발생됩니다.

근데 너지금 국비 팀프로젝트하면서 너무 오바하는거 아니야?

사실 지금 상황에는 굳이 스케일 아웃을 고려하지 않아도 되지만, 사용자에게 직접 서비스를 제공하는 개발자가 되었을때 사용자의 경험을 중요시하는 개발을 하고싶기에 지금부터 사용자의 경험을 고려한 개발을 연습해보려고 합니다.

사전에 알아야 할 것

로드밸런싱 : 대용량 트레픽을 장애없이 처리하기 위해 여러 대의 서버에 적절히 트래픽을 분배하는 것
(로드밸런싱에대한 공부가 더 필요합니다. 다만 스케일 아웃시 트래픽을 적적히 분배하는것이라고 이해하고만 있으면 됩니다.)
로드밸런서의 개념과 특징

sticky session

클라이언트는 특정 세션의 요청을 처음 처리한 서버로만 소통(request, response)을 할 수 있습니다.

A서버에서 세션을 생성했다면 이후 모든 요청은 A서버가 응답하게 됩니다.
A클라이언트 = A서버와 소통을 할 수 있는 이유는 로드밸런서 때문입니다.(로드밸런서는 쿠키를 통해 처리를 하게됩니다.)

하지만 sticky session방식도 세션을 고정해놓기 때문에 해당 WAS가 과부하가 올 수 있습니다.

Session Clustering

여러 WAS 세션을 동일한 세션으로 관리하는 것입니다.
새로운 서버가 하나 뜰 때마다 기존 WAS에 새로운 서버의 IP/Port를 입력해서 클러스터링 해줘야합니다.

👉 클러스터링이란 DB 분산 기법 중 하나로 DB 서버를 여러 개 두어 서버 한 대가 죽었을 때 대비할 수 있는 기법입니다.

즉, A, B, C 서버의 세션중 한개라도 추가, 삭제가 이루어진다면 전부 복사하여 모든 서버에 동일한 세션정보를 저장하는 것입니다.

Clustering 단점

  1. 서버가 늘어날때마다 새로운 서버의 IP/Port를 입력해서 클러스터링 해줘야합니다.
  2. 모든 서버에 세션이 복사되어있기때문에 동일한 정보를 메모리에 올려두어 효율적인 메모리 관리가 어렵습니다.
  3. 데이터 변경이 발생할때마다 모든 세션의 정보를 변경해야하기때문에 네트워크 요청 트래픽이 증가하게 됩니다.
  4. 세션을 공유(복사)할때 모든 서버에 세션이 전파되기까지의 시간차로 인한 세션 불일치 문제와 같은 예상치 못한 문제가 발생할 가능성이 존재합니다.

모든 세션이 공유하는 In-memory DB 사용하기

In-memory DB를 사용해 모든 서버가 공유하여 위의 문제를 해결 할 수 있습니다.

서버의 세션정보를 저장하지 않고 외부에 저장소를만들어 세션정보를 외부저장소에 저장하는 방법입니다.

In-memory DB를 사용하면 서버를 다중화하여 서비스를 제공해도 session정보가 외부 In-memory DB에 있기 때문에 전혀 문제가 없습니다.

  1. 특정 서버로 트래픽이 몰리는 문제가 해결되고
  2. 새로운 서버를 띄워도 전혀 문제가 없습니다.

In-memory DB단점

  1. 하나의 외부 In-memory DB를 사용하기때문에 In-memory DB가 죽는다면 모든 세션이 사라집니다.

  2. 쿠키(stateless)보다 보안은 좋아지지만, 세션정보를 세션에 저장하기때문에 접근 속도가 늦습니다.(아직 체감하지는 못했습니다...)

Redis에 의존성을 낮추기 위해 Redis도 분산화를 고려해 볼 수 있습니다.

Redis

위에서 설망한 내용을 기반으로 session을 외부 In-memory DB에 저장하기로 했습니다.

그리고 In-memory DB는 Redis를 사용하기로 했습니다.

그이유는 Redis가 다양한 자료구조를 사용할때 개발의 편의성과 생산성이 증가할 것이라고 하기 때문입니다.

다음에는 현제 OAuth로그인시 session에 jwt를 저장하였는데 이 로직은 Redis서버에 저장하여 모든 서버가 공유하도록 설계해 보겠습니다.

느낀점

아직 팀프로젝트는 서비스 운영이 되고있지 않은 시점이여서 스케일 업이나 스케일 아웃에대한 고민은 하지 않아도 되지만,
로그인을 구현하면서 Cookie, Session, Jwt에대한 공부를 하였고 자연스럽게 각각의 장단점을 알게되었습니다.

그리고 지금 Session에 jwt를 저장하는 방법으로는 스케일 아웃을 고려했을경우 사용자 경험을 낮아지고, 좋은 서비스를 제공하지 못한다는것을 깨달았습나다.

개발을 할때 단순히 어떤 기술을 사용한다가 아닌 정확한 이유가 있고 그 이유가

우리가 제공하는 서비스와 사용자에게 좋은 경험을 주는가?

라는 고민을 하면서 개발을 해야겠다고 생각했습니다.

참고자료

[Spring] 세션 불일치 문제가 발생하는 이유와 세션 불일치를 해결하는 법
스케일 업, 스케일 아웃이 궁금하다면?
로드밸런서의 개념과 특징

profile
배우고, 생각하고, 행동해라

0개의 댓글