우리가 보통 Web 을 개발할때, 유저가 누구인지 확인하는 로그인(Authentication) 절차는 필수이다.
이 때 보통 Http 요청 방식으로 많이 처리하게 되는데
나는 서버기반인증 과 토큰기반인증 크게 2개로 나누어 설명하겠다.
서버 기반 인증 (Session & Cookie)
세션 기반의 인증 시스템이다. 서버 측에서 사용자들의 정보를 기억하기 위해 세션을 유지하는데,
이는 메모리, 디스크, 데이터베이스 등을 통해 관리한다.
클라이언트로부터 요청을 받으면 클라이언트의 상태 정보를 저장하여 유지해야 하므로 Stateful 한 구조를 가진다.
[ 인증 방식 ]
- 사용자가 로그인 시 올바른 사용자임을 확인하고, 고유한 세션 ID 값을 부여해 세션 저장소에 저장하고 클라이언트에게 발급해준다.
- 클라이언트는 세션 ID를 받아 쿠키에 저장하고, 인증이 필요한 요청마다 쿠키에 세션 ID를 담아 헤더에 보낸다.
- 서버에서는 쿠키를 받아 세션 저장소와 비교해 올바른 요청인지 확인한다.
- 인증이 완료되고 서버는 요청에 응답한다.
[ 장점 ]
- 중요한 정보는 서버에 있기 때문에 쿠키 자체(세션 ID)에는 유의미한 값을 가지고 있지 않다.
[ 단점 ]
- 해커가 훔친 쿠키를 이용해 HTTP 요청을 보내면 서버에서는 올바른 사용자가 보낸 요청인지 알 수 없다.
- 사용자의 수만큼 서버에 세션을 저장하므로 그만큼 사용자가 증가하면 서버 메모리를 많이 차지하게 된다(그래서 동접자 수가 많은 웹 사이트인 경우 서버에 과부하를 주게 되므로 성능 저하의 요인)
- 시스템 확장이 어렵다.
토큰 기반 인증 (JWT)
위와 같은 일련의 과정을 극복하면서 나타난 하나의 인터넷 표준 인증 방식 이다.
인증받은 사용자에게 토큰을 발급해주고, 서버에 요청을 할 때 HTTP 헤더에 토큰을 함께 보내 인증받은 사용자(유효성 검사)인지 확인한다.
서버 기반 인증 시스템과 달리 사용자의 인증 정보를 서버에 저장하지 않고 클라이언트의 요청으로만 인가를 처리하므로 Stateless 한 구조를 가진다.
JWT는 Json Web Token의 약자로 인증에 필요한 정보를 암호화시킨 토큰을 뜻한다.
서버(Session) 방식과 유사하게 클라이언트는 Access Token(JWT)을 HTTP 헤더에 실어 서버로 보낸다.
[ 인증 방식 ]
- 사용자가 로그인 시 올바른 사용자임을 확인하고, 클라이언트에게 Access Token(JWT)을 발급해준다.
- 클라이언트는 전달받은 토큰을 저장해 두고, 인증이 필요한 요청마다 토큰을 HTTP 헤더에 담아 보낸다.
- 서버에서는 암호화된 토큰을 복호화 해 올바른 요청인지 확인한다.
- 인증이 완료되고 서버는 요청에 응답한다.
[ 장점 ]
- 서버 기반 인증 시스템은 저장소의 관리가 필요하지만, 토큰 기반은 Access Token을 발급해준 후 요청이 들어오면 검증만 해주면 되기 때문에 추가 저장소가 필요 없다. 즉 Stateless 하다.
- 쿠키를 사용함으로 인해 발생하는 취약점이 사라진다. 하지만, 토큰을 사용하는 환경에서의 취약점에 대비해야 한다.
- 확장성이 뛰어나다. 토큰 기반으로 하는 다른 인증 시스템에 접근이 가능하다.
[ 단점 ]
- 이미 발급된 JWT를 돌이킬 수 없다. 서버 기반 인증 시스템처럼 저장소를 사용하는 경우에는 해당 세션이 악의적으로 사용될 경우 지워버리면 되지만, JWT는 한 번 발급되면 유효기간이 완료될 때 까지는 계속 사용이 가능하다.
- 즉, 유효기간이 지나기 전까지 실컷 털릴 수 있다.
- JWT의 길이가 길다. 인증이 필요한 요청이 많아질수록 서버의 자원 낭비가 발생한다.
서버 기반 인증 방식은 과거에 사용하던 방식이고 이를 대체하기 위하여 등장한 것이 토큰 기반 인증 방식이지만,
토큰 기반 인증 방식을 사용한다고 해서 무조건 해킹의 위험에서 벗어난 것은 아니다.
가장 중요한 것은 개발하는 서비스의 성격에 맞게, 보안과 사용자 편의를 비교해가면서 주어진 상황을 고려하여 인증 정책을 결정하는게 맞지 않을까.
'web' 카테고리의 다른 글
[JAVA] Stream for each vs for-loop (0) | 2024.06.11 |
---|---|
[WEB] 블로킹/논블로킹 and 동기 / 비동기 (0) | 2023.11.23 |
[MSA] Spring Cloud를 사용해보자(3)-API Gateway (1) | 2023.11.22 |
[WEB][Reactor Java] Mono와 Flux를 생성하는 방법 (1) | 2023.11.08 |
[WEB] Reactive Streams (1) | 2023.11.08 |