티스토리 뷰
✔ Http는 상태가 유지되지 않는 Stateless한 무상태 프로토콜이다.
그래서 서버가 클라이언트의 상태를 기억하기 위한 다양한 방법이 존재한다.
1. 세션 기반 인증 2. 토큰 기반 인증
1. 세션 기반 인증 시스템
서버 측에서 사용자들의 정보를 기억하고 있어야 한다. 사용자들의 정보를 기억하기 위해서는 세션을 유지해야 하는데, 메모리나 디스크 또는 데이터베이스 등을 통해 관리한다. 서버 기반의 인증 시스템은 클라이언트로부터 요청을 받으면, 클라이언트의 상태를 계속해서 유지하고 이 정보를 서비스에 이용하는데, 이러한 서버를 Sateful 서버라고 한다. 예를 들어 사용자가 로그인을 하면, 세션에 사용자 정보를 저장해두고 서비스를 제공할 때 사용하곤 한다. 이러한 서버 기반의 시스템은 다음과 같은 흐름을 갖는다.
이러한 인증 방식은 소규모 시스템에서는 아직 많이 사용되고 있지만, 웹/앱 어플리케이션이 발달하게 되면서 서버를 확장하기가 어렵다는 등 다음과 같은 문제점을 보이기 시작했다.
Spring Session
임베디드 톰캣은 고유한 세션 ID(JSSEIONID)를 웹브라우저에 쿠키로 전달하고, 클라이언트에서는 서버에 요청시 해당 세션ID를 함께 전달한다. 서버는 전달받은 세션ID를 서버에 저장되어있는 정보와 비교해서 클라이언트의 상태를 지속적으로 유지하게 된다. 톰캣 라이브러리에서 정의된 인터페이스는 HttpSession이 있다.
👉 서비스 사용자가 급증해, 서버로 유입되는 트래픽이 증가하였을때 한대의 서버만으로는 부담이 크다.
서버의 부하를 줄이기 위해 서버를 증설하는 경우.
각각의 서버에서 관리하는 세션 정보는 서로 공유를 하고 있지 않다. 즉 세션 정보가 일치하지 않는 상황이 발생한다.
👉 이를 위해 aws ELB에서는 Sticky Session기능을 제공하는데 로드 밸런서에서 클라이언트가 동일한 백엔드 API 서버에 접근할 수 있도록 해준다. 즉 클라이언트는 자신의 세션 정보를 갖고 있는 특정 백엔드 서버에만 접속한다. 세션이 일치하지 앟는 상황이 발생하지 않는다. 하지만, 해당 기능은 로드 밸런싱의 기본적인 역할인 트래픽 부하 분산 역할을 완벽하게 수행할 수 없게 된다.
👉 이에 대한 해결책은 세션을 공유할 수 있는 별도의 세션 저장소를 구축하면 된다.
'Redis' 라는 비관계형 DBMS를 많이 사용한다. 스프링 세션은 세션 공유 저장소를 심플하게 구축할 수 있는 기능을 제공한다. 이렇게 웹서버와 세션 저장소를 분리한 환경은 유연하게 확장 가능하고 분산 환경에서 안정적인 서비스 운영이 가능하게 한다. (이를 세션 클러스터링이라 한다...)
✔세션 저장소를 구축하는 방법은 일반적으로 많이 사용된다.
하지만 세션 저장소에 매번 조회를 해야한다는 단점이 존재한다.
사용자의 요청이 있을때마다 권한이 있는지 검증하기 위해서는 매번 세션 저장소에서 데이터를 조회해야 한다.
세션 저장소에 매번 조회하지 않고 인증 및 인가 기능을 구현할 수 있는 방법이 있다.
그것은 바로 토큰 기반 인증 시스템.
2. 토큰 기반 인증 시스템
토큰 기반의 인증 시스템은 인증받은 사용자들에게 토큰을 발급하고, 서버에 요청을 할 때 헤더에 토큰을 함께 보내도록 하여 유효성 검사를 한다. 이러한 시스템에서는 더이상 사용자의 인증 정보를 서버나 세션에 유지하지 않고 클라이언트 측에서 들어오는 요청만으로 작업을 처리한다. 즉, 서버 기반의 인증 시스템과 달리 상태를 유지하지 않으므로 Stateless한 구조를 갖는다. 이러한 토큰 기반의 인증 방식을 통해 수많은 문제점들을 해결할 수 있는데, 대표적으로 사용자가 로그인이 되어있는지 안되어있는지 신경쓰지 않고 손쉽게 시스템을 확장할 수 있다.
이러한 토큰 기반의 인증 시스템은 아래와 같은 과정으로 작동한다.
- 사용자가 아이디와 비밀번호로 로그인을 한다.
- 서버 측에서 해당 정보를 검증한다 -> 검증된 후 사용자에게 Signed 토큰을 발급한다. (Signed는 해당 토큰이 서버에서 정상적으로 발급된 토큰임을 증명하는 Signature를 가지고 있다는 것)
- 클라이언트 측에서 전달받은 토큰을 저장해두고
서버에 요청을 할 때마다 Http 요청 헤더에 해당 토큰을 함께 보낸다. - 서버는 토큰이 해당 서버에서 생성한 것이 맞는지만 검증하고 요청에 응답한다.
장점
- 무상태성(Stateless) & 확장성(Scalability)
토큰은 클라이언트 측에 저장되기 때문에 서버는 완전히 Stateless하며, 클라이언트와 서버의 연결고리가 없기 때문에 확장하기에 매우 적합하다. 만약 사용자 정보가 서버 측 세션에 저장된 경우에 서버를 확장하여 분산처리 한다면, 해당 사용자는 처음 로그인 했었던 서버에만 요청을 받도록 설정을 해주어야 한다. 하지만 토큰을 사용한다면 어떠한 서버로 요청이 와도 상관이 없다. - 보안성
클라이언트가 서버로 요청을 보낼 때 더 이상 쿠키를 전달하지 않으므로, 쿠키 사용에 의한 취약점이 사라지게 된다. 하지만 토큰 환경의 취약점이 존재할 수 있으므로 이에 대비해야 한다. - 확장성(Extensibility)
시스템의 확장성을 의미하는 Scalability와 달리 Extensibility는 로그인 정보가 사용되는 분야의 확정을 의미한다. 토큰 기반의 인증 시스템에서는 토큰에 선택적인 권한만 부여하여 발급할 수 있으며 OAuth의 경우 Facebook, Google 등과 같은 소셜 계정을 이용하여 다른 웹서비스에서도 로그인을 할 수 있다. - 여러 플랫폼 및 도메인
서버 기반 인증 시스템의 문제점 중 하나인 CORS를 해결할 수 있는데, 애플리케이션과 서비스의 규모가 커지면 여러 디바이스를 호환시키고 더 많은 종류의 서비스를 제공하게 된다. 토큰을 사용한다면 어떤 디바이스, 어떤 도메인에서도 토큰의 유효성 검사를 진행한 후에 요청을 처리할 수 있다. 이런 구조를 통해 assests 파일(Image, html, css, js 등)은 모두 CDN에서 제공하고, 서버 측에서는 API만 다루도록 설게할 수 있다.
대표적으로는 JWT (Json Web Token) 방식이 있다.
JWT 및 토큰 기반 인증 시스템의 장점
백엔드 서버가 여러대인 상황에서 클라이언트의 토큰이 유효한지 검증하기 위해서는
모두 동일한 시크릿 키를 가지고 있어야 한다. JWT 토큰에 대한 검증을 서버에서 직접 하기 때문이다.
이 JWT의 장점은 세션ID를 세션 저장소에 따로 저장하지 않아도 된다는 것이다.
요청이 올 때마다 세션 저장소에 조회를 하지 않아도 된다는 것은 백엔드 시스템의 부하를 줄이며, 심플하고 안정적인 인증 시스템을 구축할 수 있다는 것이다.
단점
SecretKey가 노출 된다면 시스템 보안의 큰 문제가 생긴다는 것이다.
키 관리가 매우 중요한 문조가 되겠다.
어떤 것을 선택하든 장단점이 존재한다. 상황에 따라 적절히 선택하는 것이 중요하겠다.
Reference:
'컴퓨터 기본지식(CS) > Server' 카테고리의 다른 글
파일 전송 명령어 - scp / docker cp (0) | 2022.11.01 |
---|---|
CORS 정책 (0) | 2022.05.27 |
도커란? (0) | 2022.02.07 |