본문 바로가기
CS 지식/네트워크

[네트워크] JWT 토큰 인증 (쿠키, 세션, 토큰 인증 방식)

by ghan2 2024. 6. 9.

기본적이면서도 헷갈리는 개념인 쿠키, 세션, 토큰에 대해 공부해보았다.

이 세 가지 개념은 로그인을 구현할 때 빠질 수 없이 나오는 키워드 들인 것 같다. 

서버가 클라이언트의 인증을 확인하는 방법으로 쿠키, 세션, 토큰 방식 이렇게 3가지가 있다고 한다.

먼저 각각의 방식을 살펴보자!

 

🍪 쿠키: 클라이언트(브라우저)가 가지고 있는 정보

쿠키는 브라우저에 저장되는 key-value형식의 문자열 덩어리다. 클라이언트가 어떠한 웹 사이트를 방문할 경우 그 사이트가 사용하고 있는 서버를 통해 브라우저에 설치되는 작은 기록 정보 파일이다. 즉 클라이언트가 가지고 다니는 정보라고 할 수 있다. 

쿠키 인증 방식은 브라우저가 서버에 요청을 보내고 서버는 응답을 쿠키에 작성하여 보낸다. 

쿠키 방식의 단점

- 가장 큰 단점은 보안에 취약하다는 점이다.. 요청 시에 쿠키의 값이 유출 및 조작 당할 위험이 존재한다.

- 쿠키에는 용량 제한이 있어서 많은 정보를 담을 수 없다

- 웹 브라우저간 공유가 불가능하다

- 쿠키의 사이즈가 커질수록 네트워크에 부하가 심해진다.

 

따라서 쿠키는 당사자뿐만 아니라 제3자가 조회하는 것도 가능하기 때문에 개인 정보를 담은 내용이나 보안상 민감한 정보를 저장하는 데에는 적합하지 않다. 따라서 보안상 크게 문제되지 않을 정보를 브라우저에 저장함으로써 웹사이트의 이용을 편리하게 해주는 역할을 주로 한다. 예를 들면 자주 보는 쇼핑몰 목록이나 웹 페이지의 다크 모드 설정 여부와 같은 정보가 있다.

 

🏢 세션: 서버가 가지고 있는 정보

쿠키의 보안적인 이슈 때문에, 세션은 비밀번호 등 클라이언트의 민감한 인증 정보를 브라우저가 아닌 서버 측에 저장하고 관리한다. 서버의 메모리에 저장하기도 하고, 서버의 로컬 파일이나 데이터베이스에 저장하기도 한다. 세션 객체는 key 에 해당하는 session id와 이에 대응하는 value로 구성되어 있다. value에는 세션 생성 시간, 마지막 접근 시간 및 User가 저장한 속성 등이 Map 형태로 저장된다.

https://img1.daumcdn.net/thumb/R800x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5Prwl%2FbtrN6mOFyuh%2FflbYdwL2GiAC1ISFLnwSiK%2Fimg.png

유저가 웹사이트에서 로그인하면 세션이 서버 메모리(혹은 데이터베이스)상에 저장된다. 이때, 세션을 식별하기 위한 session id를 기준으로 정보를 저장한다. 이후 서버에서 브라우저에 session id를 담은 쿠키를 보낸다. 쿠키에 정보가 담겨있기 때문에 브라우저는 해당 사이트에 대한 모든 요청에 아이디 정보를 담아 전송한다. 서버는 이 아이디 값을 가지고 인증을 수행한다.

 

세션 방식의 단점

- 세션 아이디 자체는 유의미한 개인정보를 담고 있지는 않지만 세션 ID를 탈취하여 클라이언트인척 위장할 수 있다는 한계가 존재한다. (서버에서 IP를 특정하면 일부 해결 가능하다)

- 서버에서 세션 저장소를 사용하므로 요청이 많아지면 서버에 부하가 심해진다.

 

🧩 토큰: 세션과는 또 다른 로그인 유지 방식

세션 방식은 안전하고 효과적이지만 단점도 있다. 서버는 요청마다 함께 딸려 오는 세션 아이디를 바로바로 확인할 수 있도록 로그인한 사용자의 아이디를 메모리라는 '책상'위에 올려둔다. 메모리에 올려둔 데이터를 빠르게 확인할 수 있다는 장점이 있는 대신 공간이 한정되어 있다. 또한 서버에 동시 접속하는 사용자가 많아질수록 메모리 공간이 부족해져서 서버에 부하가 걸리게 될 것이다. 이처럼 메모리 공간을 많이 차지하는 세션 방식의 대안으로 나온 것이 토큰 방식의 인증이다. 

 

토큰 기반 인증은 클라이언트가 서버에 접속하면 인증되었다는 의미로 '토큰'을 발급후 부여한다. 이 토큰은 유일하며 토큰을 발급받은 사용자는 또 다른 서버에 요청을 보낼 때 요청 헤더에 토큰을 심어 보낸다. 그러면 서버에서는 클라이언트로부터 받은 토큰을 서버에서 제공한 토큰과의 일치 여부를 체크하여 인증 과정을 처리한다. 이러한 토큰에는 특수한 수학적 원리가 적용되어 있어서 마치 위조 방지 장치가 있는 것처럼 서버만이 유효한 토큰을 발행할 수 있다.

 

토큰 방식의 단점

- 쿠키/세션과 다르게 토큰 자체의 데이터 길이가 길어, 인증 요청이 많아질수록 네트워크 부하가 심해질 수 있다. 

- payload 자체는 암호화되지 않기 때문에 유저의 중요한 정보는 담을 수 없다.

- 토큰을 탈취당하면 대처하기 어렵다. (따라서 사용 기간을 짧게 설정하여 구현한다.)

 

JWT (JSON Web Token) 이란?

인증에 필요한 정보들을 암호화시킨 JSON 토큰을 말한다. 그리고 JWT 기반 인증은 JWT토큰(Access Token)을 HTTP 헤더가 실어 서버가 클라이언트를 식별하는 방식이다. JWT는 JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것이며, 토큰 내부에는 위변조 방지를 위해 개인키를 통한 전자서명도 들어있다. 따라서 사용자가 JWT를 서버로 전송하면 서버는 서명을 검증하는 과정을 거치게 되며 검증이 완료되면 요청한 응답을 돌려준다. 

 

JWT의 구조는 Header, Payload, Signature를 가진다. 

Header: JWT에서 사용할 타입과 해시 알고리즘의 종류가 담겨있다.

Payload: 서버에서 첨부한 사용자 권한 정보와 데이터가 담겨있다.

Signature: 헤더, 페이로드를 인코딩한 이후 헤더에 명시된 해시 함수를 적용해고, 개인키로 서명한 전자서명이 담겨있다.

 

💡 복호화를 통해 정보가 유출될 위험은 없는가?
Header와 Payload는 단순히 인코딩된 값이기 때문에 제3자가 복호화 및 조작할 수 있지만, Signature는 서버측에서 관리하는 비밀키가 유출되지 않는 이상 복호화할 수 없다. 따라서 시그니처는 토큰의 위변조 여부를 확인하는 데 사용된다.

 

JWT를 이용한 인증 과정은 이렇다.

1) 사용자가 로그인 인증 요청

2) 요청을 받은 서버는 헤더, 페이로드, 시그니처를 정의하고 이를 각각 Base64로 한 번 더 암호화하여 JWT를 생성하고 이를 쿠키에 담아 클라이언트에게 발급한다.

3) 클라이언트는 서버로부터 받은 JWT를 로컬 스토리지에 저장한다. 그리고 요청을 보낼 때 Authorization header에 Access Token을 담아서 보낸다.

4) 서버는 해당 서버가 발행한 토큰이 맞는지 검증하고 인증과정을 거친다.

5) 클라이언트가 요청시에 만일 엑세스 토큰의 시간이 만료되면 클라이언트는 리프래시 토큰을 이용하여 서버로부터 새로운 엑세스 토큰을 발급 받는다.

 

JWT의 장점

- 헤더와 페이로드를 가지고 시그니처를 생성하므로 데이터 위변조를 막을 수 있다.

- 인증 정보에 대한 별도의 저장소가 필요없다.

- 세션과 다르게, 서버가 무상태(StateLess)가 되어 서버 확장성에 우수해질 수 있다.

- 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다.

- 모바일 어플리케이션 환경에서도 잘 동작한다. (모바일은 세션 사용 불가능)

 

JWT의 단점

- 토큰 자체에 정보를 담고 있다는 점이 양날의 검이 될 수 있다.

- 토큰의 정보가 많아질수록 길이가 길어지면 네트워크에 부하를 줄 수 있다.

- 토큰 자체를 탈취당하면 대처하기 어렵다.

 

다만 이 JWT도 제 3자에게 탈취의 위험성이 있기에 그대로 사용하지 않고 Access Token, Refresh Token으로 이중으로 나누어 인증을 하는 방식을 택한다. 

 


참고

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-JWTjson-web-token-%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC#cookie_/_session_/_token_%EC%9D%B8%EC%A6%9D_%EB%B0%A9%EC%8B%9D_%EC%A2%85%EB%A5%98

https://hongong.hanbit.co.kr/%EC%99%84%EB%B2%BD-%EC%A0%95%EB%A6%AC-%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%ED%86%A0%ED%81%B0-%EC%BA%90%EC%8B%9C-%EA%B7%B8%EB%A6%AC%EA%B3%A0-cdn/