사용자 인증 - Session vs Token(JWT)
HTTP 통신 특성
인증 방식에 대해 설명하기 앞서 HTTP 통신 특성에 대해 얘기해보자면..
기본적으로 HTTP는 stateless한 특성을 가지기 때문에 각 통신의 상태가 저장되지 않는다. 그렇기 때문에 사용자가 웹 서비스에 로그인하여 서비스 이용 시 새 페이지를 요청할 때마다 로그인을 해줘야 되는 문제가 발생할 수 있다.
이 때 세션과 토큰을 사용하면 위 문제를 해결할 수 있다.
- 사용자가 로그인을 시도할 때 서버에서 일치하는 유저 정보를 찾아 인증(Authentication) 확인의 표시로 session이나 token을 발급,전달
- 웹 브라우저에서 session/token 정보를 받아 가지고 있다가 새로운 request 발생 시 인가(Authorization)를 위해 해당 세션/토큰을 함께 전송
Session/Token 의 차이
우선 가장 큰 차이점은 세션은 데이터베이스 서버에 저장되고 토큰은 클라이언트에만 저장된다는 점이다.
그 외 차이점은 크게 안정성과 확장성 관점에서 비교해볼 수 있다.
1. 안정성
세션은 서버에서 저장/관리하기 때문에 상대적으로 상태를 유지하기 유리하고 유효기간,HttpOnly,Secure 등 옵션을 쿠키에 저장하여 외부 공격에 대비할 수 있다.
반면에 토큰은 웹 브라우저에 저장되기 때문에 공격에 노출될 가능성이 더 크므로 토큰에는 민감한 정보를 담지 않는다.
유효기간 역시 짧게 설정하여 공격에 노출될 수 있는 시간을 최소화한다.
하지만 짧은 주기로 토큰이 expired 되면 사용자는 매번 다시 로그인을 해줘야 하기 때문에 refreshToken을 함께 발급해서 이를 보완한다.
2. 확장성
대부분의 웹 서비스가 토큰 방식을 선택하게 된 이유가 바로 확장성 측면에서의 문제 때문이다.
위에서 설명한 대로 세션은 서버에 저장되기 때문에 한 번에 여러 접속자가 들어오게 되면 과부하가 발생할 수 있다.
이 경우 서버를 분산해서 사용할 수 있으나 이에 따른 비용이 추가로 발생하기 때문에 토큰 방식을 선호한다.
Sessiong 기반 인증
세션 기반 인증은 토큰 기반 인증이 없었을 때 사용했던 방식으로 서버 세션을 사용해 사용자 인증을 할 수 있다.
대략적인 프로세스는 아래와 같다.
- 클라이언트 로그인
- 로그인 성공 시 서버가 유저 세션 생성하여 메모리 혹은 데이너베이스에 저장
- 서버에서 클라이언트에 세션 ID 전송
- 클라이언트 브라우저에 세션 ID만 쿠키에 저장
이 경우 세션 데이터가 서버의 메모리에 저장되기 때문에 서버 확장 시 모든 서버가 접근할 수 있도록 별도의 중앙 세션 관리 시스템이 필요하다.
단점
- 중앙 세션 관리 시스템이 없으면 시스템 확장이 어렵다.
- 중앙 세션 관리 시스템의 영향을 받아 시스템 장애 발생 시 전체에 문제가 발생한다.
- 상황에 따라 메모리 사용량이 많아질 수 있다.
그래서 규모 확장이 고려되지 않는 소규모 프로젝트에서는 세션 기반 인증 방식을 사용하기도 한다.
JWT(Json Web Token)
JWT는 토큰 기반 인증 방식으로 클라이어트의 세션 상태를 저장하여 관리하는 것이 아니라 필요한 정보를 토큰 body에 저장하여 클라이언트가 가지고 있고 해당 토큰을 인증서처럼 사용한다.
- 사용자가 로그인을 하면 클라이언트가 서버로부터 accessToken을 부여받음
- 이후 클라이언트에서 api 요청 시 모두 accessToken을 포함시킴
- 서버는 accessToken을 해독하여 검증되면 해당 api 기능을 수행
- accessToken 만료 시 refreshToken으로 서버에서 새로운 accessToken을 발급받음
- 반복
JWT에 대한 자세한 설명은 다음 글에 이어서..
Reference