백엔드

[백엔드] jwt vs session

happy_life 2023. 4. 13. 11:23

이번 포스팅에서는 인증 방식인 jwt와 session을 비교하고, 각각의 특징을 정리해보려고 합니다. 현재 프로젝트에서 회원 관리 API를 설계하려고 하는데 그 전에 회원을 인증하는 방식을 jwt 와 session 중 어떤 것을 활용해 구현할지를 고민하고 있습니다. 이에 jwt와 session 방식을 비교해 선택하기로 결정하였고, 이 과정을 포스팅하려고 합니다.

 

 

Session

1. Session이 필요한 이유

HTTP 프로토콜은 비상태성(Stateless)와 비연결성(Connetionless) 특징을 가지고 있습니다.  서버간의 연결을 유지하지 않음으로써 서버의 리소스를 효율적으로 사용하고, 클라이언트의 상태를 유지하지 않음으로써 서버의 부하를 줄이기 위함입니다.  하지만 이런 특징들은 상태를 유지해야 하는 경우에는 문제가 될 수 있습니다.  예를 들어, 웹페이지에 로그인 한 경우, 사용자의 상태가 필요하기 때문입니다. 이런 경우 쿠키, 세션을 사용하여 상태를 유지합니다.

 

2. Cookie

쿠키는 서버가 사용자의 웹 브라우저에 저장하는 데이터입니다. 서버가 쿠키와 함께 클라이언트에 응답을 보내면, 클라이언트는 매번 저장된 쿠키를 헤더에 포함해 요청을 보내게 됩니다. 하지만 이러한 쿠키는 몇 가지 단점이 있습니다.

 

쿠키의 단점

1. 보안 문제

- 쿠키에는 개인 식별 정보가 포함될 수 있으므로, 해커가 유출된 쿠키를 사용하여 사용자인 것처럼 위장하거나, 인증 정보를 탈취할 수 있습니다.

 

2. 개인 정보 보호 문제

- 쿠키에는 사용자가 방문한 웹 사이트와 관련된 정보가 저장됩니다. 일어한 정보는 사용자의 개인 정보와 관련되어 있습니다.

 

3. 용량 문제

- 쿠키의 크기에는 제한이 있으며, 큰 데이터를 저장하려면 여러 개의 쿠키를 사용해야 합니다. 이는 서버 측에서 쿠키를 처리하는데 추가 비용을 야기합니다.

 

4. 권한 문제

- 쿠키는 클라이언트 측에 저장되므로, 클라이언트 측에서 수정이 가능합니다. 예를 들어, 클라이언트 측에서 쿠키 값을 변경하여 더 많은 권한을 부여받을 수 있습니다.

 

이러한 문제를 해결하기 위해 Session이 필요하게 되었습니다.

 

3. 세션

세션은 쿠키와 달리 서버 측에서 데이터를 저장하므로, 쿠키에 비해 상대적으로 안전합니다. 세션 ID는 일반적으로 쿠키를 사용하여 클라이언트에게 전달되지만, 이는 세션ID만 저장하므로 보안상의 문제를 크게 야기하지 않습니다. 또한 세션이 쿠키보다 용량이 크고, 클라이언트에 저장되지 않으므로, 권한 문제 등도 발생하지 않습니다. 하지만 세션에도 몇 가지 단점이 있는데 이는 아래와 같습니다.

 

*세션의 단점

1.  서버 자원 사용

- 세션은 서버 측에서 상태를 유지하므로, 서버 자원을 사용합니다. 많은 사용자가 동시에 접속하면, 서버 자원의 부담이 증가합니다.

 

2. 로드 밸런싱 문제

- 세션은 서버 측에서 상태를 유지하므로, 로드 밸런싱을 수행ㅎ아는 경우, 세션 정보를 공유할 수 있도록 세션 정보를 별도의 저장소에 저장해야 합니다.

 

3. 보안성 문제

- 세션 ID가 탈취될 경우, 세션 하이재킹을 당할 수 있습니다. 해커가 세션 ID를 탈취하여 해당 사용자의 계정에 로그인하면, 해당 사용자의 권한으로 웹 어플리케이션을 조작할 수 있게 됩니다.

 

* 세션의 특징

1. 클라이언트가 종료(브라우저 종료) 시 sesssion id가 제거되고, 서버에서도 세션이 제거됩니다.

2. 로그아웃하고 다시 로그인하면 새로운 사용자로 인식해 새로운 세션이 생성됩니다.

 

 

 

JWT

jwt

 

1. jwt 구성

JWT는 세파트로 나뉘고 위와 같이 구분됩니다.

 

Header: JWT의 유형과 알고리즘을 포함하는 부분

Payload: 클라이언트와 서버 간에 전달되는 정보를 포함하는 부분. 이 파트에 사용자 정보, 권한 정보 등이 포함됩니다.

Signature: JWT의 유효성을 검증하기 위한 서명정보가 있는 부분. 이 파트에서 Header와 Payload를 합친 후, 지정된 알고리즘으로 암호화된 값입니다.

 

2. jwt 통신 과정

jwt 통신 과정

 

* JWT 생성 과정

1. JWT Header와 Payload를 Json 형태로 생성합니다.

2. 생성된 Header와 Payload를 합쳐 하나의 문자열로 만들고 인코딩합니다.

3.  서버에서 비밀키를 사용하여 Header와 Payload를 서명합니다.

4. 서명한 값도 인코딩하여 JWT의 마지막 파트에 추가합니다.

 

 

Q) 클라이언트에서 로그인 요청을 보낼 때, 아이디와 비밀번호 등의 민감한 정보가 탈취될 수 있지 않나?

그렇기 때문에 HTTPS(SSL/TLS) 프로토콜을 사용하여 데이터를 암호화하고 전송해야 합니다.

 

*JWT 인증 과정

1. 받은 JWT에서 Header와 Payload를 추출합니다.

2. Header에서 지정된 알고리즘으로 Payload와 서버에서 저장한 비밀키를 사용하여 Signature를 생성합니다.

3. 생성된 Signature와 마지막 파트에 포함된 Signature를 비교합니다.

4. Signature가 일치하는 경우, JWT가 유효하다고 판단합니다.

 

Q) JWT의 Payload는 base64로 인코딩만 되어있기때문에, 탈취해서 디코딩하면 사용자 정보를 얻을 수 있다. 그러면 쿠키랑 다를 것이 없는데 왜 JWT를 사용할까?

JWT는 서명이 있어 JWT가 변조되지 않았음을 검증하는데 사용됩니다. 서명은 비밀키를 통해 생성되기 때문에, 이 비밀키를 알지 못하는 해커는 JWT를 변조할 수 없습니다. 또한 JWT인증은 Signature을 통해 체크하므로, Payload만 있다고 클라이언트처럼 로그인 권한을 부여받을 수 있는 것은 아닙니다.