쿠기, 세션 그리고 토큰
쿠기, 세션 그리고 토큰은 무엇이고 어떤 차이가 있을까?
쿠키, 세션, 토큰 같은 기능들은 Auth(인증) 기능을 구현할 때 사용하게 된다.
서로 어떤 의미이고, 어떤 연결을 했고, 어떤 차이를 알기전에 용어를 간략하게 정리해보겠다.
쿠키
: 서버와 클라이언트 간 매캐체세션
: 쿠키랑 비슷, 대신 서버 쪽에 정보를 저장토큰
: 서버에게 보여줘야 하며, 서버가 기억하는 이상하고 긴 stringJWT
: 정보를 갖고 있는 토큰, DB 없이 검증 가능
필요성
웹사이트를 이용할 때 쓰는 프로토콜 HTTP는 stateless(무상태성) 라는 특징을 갖고 있다.
- 서버로 가는 모든 요청이 이전 요청과 독립적으로 다뤄진다는 뜻
- 요청이 끝나면 서버는 우리가 누군지 잊어버린다.
그래서 서버로 요청할 때마다 우리가 누군지 알려줘야 한다.
이를 위한 방법에는 두가지 방법이 있다.
쿠키 & 세션
기반 인증JWT
기반 인증
쿠키
쿠키
는 서버가 우리에 관한 것을 기억하기 위해 우리의 브라우저에 데이터를 넣을 수 있는 시스템, 즉 그냥 서버와 클아이언트 사이의 매개체 라고 생각할 수 있다.
쿠키
는 공개 가능한 정보를 사용자의 브라우저에 저장시킨다.
쿠키의 동작 과정
서버는 클라이언트의 로그인 요청에 대한 응답을 작성할 때, 클라이언트 측에 저장하고 싶은 정보를 응답 헤더의
set-cookie
에 담는다.이후 클라이언트가 재요청 할 때마다 저장된 쿠기를 요청 헤더의
cookie
에 담아 보낸다.서버는 쿠키에 담긴 정보를 바탕으로 해당 요청의 클라이언트가 누군지 식별할 수 있다.
세션
세션
은 클라이언트와 웹서버 간 네트워크 연결이 지속 유지되고 있는 상태를 말한다.
만역 사용자의 로그인 상태를 유지하는 기능을 위해 쿠키에 아이디와 비밀번호를 담아두고 있다면,
개인 소유가 아닌 컴퓨터에서 사용할 경우 사용자의 개인정보가 노출되고,
http로 개인정보를 주고 받다보면 쿠키가 유출, 조작이 될 수 있는 보안상 큰 문제가 일어난다.
하지만 세션
은 비밀번호와 같은 인증 정보를 쿠키에 저장하지 않고 대신에 사용자의 식별자인 session ID
를 저장한다.
클라이언트와 서버 간 연결이 활성화된 상태로, 쿠키와 마찬가지로 로그인과 같은 사용자 인증을 할때 주로 사용된다.
세션은 서버에 저장하기 때문에 사용자가 늘어난다면 해당 유저의 정보를 찾고 데이터 매칭에 오랜 시간이 걸리면서 서버에 부하가 가해진다.
쿠키와 세션의 차이
쿠키
는 클라리언트에 정보를 저장세션
은 서버에 정보를 저장
쿠키와 세션 기반 인증 방식
만약 로그인을 하려고 한다면
‘봄이슝’ 유저가 로그인을 하려면 ‘봄이슝’의 정보(이름, 비밀번호)를 서버에 보낸다.
비밀번호가 맞다면, 서버는 세션 DB에
봄이슝
라는 유저를 생성한다.각 세션마다 별도의
ID
있어서 해당session ID
는 쿠키를 통해 브라우저로 돌아오고 저장한다.따라서 같은 웹사이트의 다른 페이지로 이동하면, 브라우저는
session ID
를 갖고 있는 쿠키를 자동으로 서버에서 보내게 된다.서버는
session ID
와 함께 오는 쿠키를 확인하지만, 아직까지 이session ID
의 주인이 누군지 알지 못하는 상태이다. 그저session ID
가 있는 쿠키를 지닌 요청이 있다는 것만 인지하고 있을 뿐이다.
이제 서버는 해당
session ID
를 가지고session DB
를 확인한다.- 그리고 거기서 이
ID
가봄이슝
라는 유저네임을 지닌 유저의 것이라는 것을 알게 된다.
- 그리고 거기서 이
중요한 유저 정보는 모두 서버에 있다는 점
유저가 갖고 있는 건 오직
session ID
뿐쿠키는 그저
session ID
를 전달하기 위한 매개체일 뿐
토큰
세션 방식은 안전하고 효과적이지만 단점이 있다.
위에서 설명한 사용자가 늘어나면 메모리 공간이 부족해지고 서버에 부하가 가해진다 했다.
메모리 공간을 많이 차지하는 세션 방식의 대안은 로그인한 사용자에게 session ID
대신 토큰
을 발급해 주는 것이다.
토큰은 이렇게 이상하고 무지 긴 string이다.
서버에게 보여줘야 하는 신분증 같은 거라고 생각할 수 있다.
토큰에는 여러 종류가 있는데 그 중 많이 사용하는 JWT
를 알아보겠다.
JWT
Json Wep Token의 약자로 웹에서 쓰이는 json 토큰이다.
JWT
에는 2가지 종류가 있다.
access token
: 로그인 정보에 접근할 수 있는 카드키refresh token
: 카드키 재발급
JWT 인증 방식
만약 로그인을 하려고 한다면
‘봄이슝’ 유저가 로그인을 하려면 ‘봄이슝’의 정보(이름, 비밀번호)를 서버에 보낸다.
JWT 기반 인증 방식에서는 유저네임, 비밀번호가 맞다면, 서버가 DB에 뭔가를 생성하지 않는다. (DB 필요❌)
대신 서버는 유저의 ID를 가져다가
access token
과 같은 사인된 정보를string
값으로 보내준다.이제 ‘봄이슝’가 서버에 요청을 하기 위해서는 이 토큰을 같이 보내줘야 한다.
서버는 토큰을 받으면 해당 사인이 유효한지 체크하고, 토큰이 유효하다면 그제서야 ‘봄이슝’를 유저로 인증해준다.
- 여기서 유효한지 체크한다는 것은 토큰이 조작되었는지 확인하는 과정이다.
어떤 인증 방식이 좋을까?
아래는 요즘 핫한 ChatGPT에서 물어본 것이다.
특성 | 세션 | 토큰 |
---|---|---|
유형 | 서버 측에 저장됨 | 클라이언트 측에 저장됨 |
보안 | 서버에 저장되어 보안에 우수함 | 클라이언트에서 관리되므로 보안성이 낮을 수 있음 |
유효 시간 | 보통 세션 시간과 함께 서버에서 설정됨 | 토큰의 만료 시간이 설정되어 있음 |
확장성 | 세션 저장소의 용량 제한이 있을 수 있음 | 일반적으로 확장 가능함 |
관리 용이성 | 클라이언트 관리가 필요 없음 | 클라이언트에서 관리해야 함 |
중재 | 세션 유지에 대한 중재가 필요함 | 클라이언트 측에서 자체적으로 중재 가능 |
네트워크 트래픽 | 요청마다 세션 식별자가 함께 전송됨 | 요청마다 토큰이 함께 전송됨 |
확장성 | 세션 저장소의 용량 제한이 있을 수 있음 | 일반적으로 확장 가능함 |
재인증 | 세션 만료 시 서버에서 새로운 인증이 필요함 | 토큰이 만료되면 새로운 토큰을 요청해야 함 |
디바이스 독립성 | 디바이스와 무관함 | 클라이언트 디바이스에 종속적일 수 있음 |
세션 방식
세션 방식에서 서버는 로그인 된 유저의 모든 정보를 세션 DB에 저장합니다. 이 정보들을 이용하면 새로운 기능들을 추가할 수 있게 된다.
원하지 않는 디바이스에서 강제 로그아웃을 할 수 있게 하거나,
OTT 서비스에서 계정 공유 숫자를 제한할 수 있습니다. 현재 로그인을 몇명이 했고, 몇명이 시청하는지 알 수 있습니다.
다만, 이렇게 다 알기 위해서는 DB를 반드시 사고, 유지해야 합니다. 게다가 유저가 늘어나면 늘어날수록 DB도 커져야 한다는 점을 유의해야 한다.
JWT 방식
JWT를 사용하면 생성된 토큰을 추적하지 않는다.
서버는 오직 토큰이 유효하지만 살펴볼 뿐이다.
세션 DB를 따라 살 필요가 없다.
하지만 토큰을 추적하지 않기 때문에 세션 방식에서 말한 강제 로그아웃과 같은 기능은 구현할 수 없다.
- 해당 토큰이 만료되기 전까지는 유효하기 때문이죠.
그렇다고 JWT가 별로인 것은 아니다.
DB 없이도 데이터를 사인하고, 유저에게 보내고, 해당 데이터를 돌려받을 때 유효성을 검증할 수 있기 때문이다.
유의해야 할 점은 JWT의 payload는 암호화되지 않기 때문에 토큰을 탈취당할 위험이 있어 유저의 중요한 정보를 담을 수 없다는 점이다.
참고