IT/Computer Science

세션 vs 토큰 vs 쿠키

무녈 2021. 10. 6. 10:56

해당 내용은 노마드코더 '세션 vs 토큰 vs 쿠키' 영상을 보고 정리한 것입니다.


세션 vs 토큰 vs 쿠키

Auth(인증)을 통해 서비스는 유저를 검증할 수 있다.

Auth를 만들어야 한다면 쿠키, 세션, 토큰, JWT 같은 단어를 들어봤을 것이다.

쿠키, 세션, 토큰, JWT 아직도 헷갈리고 뭐가 무엇인지 정확히 구분이 가지않았다.

이 단어들의 각각 의미가 무엇이고, 어떻게 연결되는지 알아보자!

쿠키 

쿠키 vs 토큰

결론적으로 쿠키와 토큰은 아주 다른것이다.

쿠키

쿠키를 이용해서, 서버는 클라이언트에 관한 것을 기억하기 위해 클라이언트의 브라우저에 데이터를 넣을 수 있다.

클라이언트가 사이트에 방문할 경우, 브라우저는 서버에 요청을 보내고 서버는 이에 응답(response)을 실시한다.

응답에는 모든 데이터와 클라이언트가 찾던 페이지 정보가 있고, 또한 브라우저에 저장하고자 하는 쿠키가 존재할 수 있다.

클라이언트가 브라우저에 쿠키를 저장한 뒤, 해당 웹사이트를 방문할 때마다 브라우저는 해당 쿠키도 요청과 함께 보내게 된다.

  • 참고: 쿠키는 도메인에 따라 제한이 된다.
    ex) 유튜브가 준 쿠키는 유튜브에만 보내지게된다.

쿠키는 유효기간이 존재한다.

  • 어떤 쿠키는 하루, 혹은 한달 등 서버가 정한 기간에 따라 유효

쿠키는 인증 뿐만 아니라, 여러가지 정보를 저장할 수 있다.

ex) 웹사이트 언어설정을 바꾸면, 서버는 쿠키를 주고, 클라이언트가 선택한 언어를 저장한다. 따라서, 다음에 클라이언트가 해당 웹사이트에 방문할 때

쿠키는 요청과 함께 서버로 보내지고,

서버는 쿠키가 기억해둔 언어설정의 페이지를 제공한다.

세션과 토큰

세션과 토큰이 왜 필요한지 이해하기 위해, HTTP의 성격을 알아야한다.

HTTP는 웹사이트를 이용할때 쓰는 프로토콜로 해당 프로토콜은 stateless이다.

  • stateless: 서버로 가는 모든 요청이, 이전 리퀘스트와 독립적으로 다루어진다는 것, 요청끼리 연결과 메모리가 없다.
    요청이 끝나면 서버는 클라이언트가 누군지 잊어버리게된다. 요청할 때마다, 요청자가 누군지 알려주어야한다.

이런 방법 중 하나가 바로 세션(Session)과 Token

세션

ex) "Nico"이라는 유저명이 있고, 로그인하고 싶다면, 유저명과 비밀번호를 서버에 보내게된다.

비밀번호가 맞다면, 서버는 세션 DB에 'Nyol'이라는 유저를 생성한다.

해당 세션에는 별도의 ID가 존재

해당 세션 ID는 쿠키를 통해 브라우저로 돌아오고, 저장된다.

따라서 같은 웹사이트의 다른 페이지로 이동하면, 브라우저는 세션 ID를 갖고있는 쿠키를 서버에게 보낸다.

왜냐하면 쿠키는 자동으로 보내지기 때문!

서버는 들어오는 쿠키를 보고, 세션 ID와 함께 오는 쿠키를 확인한다.

아직까지도 서버는 클라이언트가 누구인지 모른다.

세션 ID가 있는 쿠키를 지닌 요청이 있다는 것만 알 뿐

해당 세션 ID를 가지고 세션 DB를 확인하고,

거기서 해당 ID는 유저명이 Nico의 것이라는 것을 알게 되고,

그제서야, 서버는 클라이언트가 누구인지 알게되고, 바로 그때 '환영해요 Nico"와 같은 메세지를 띄울 수 있게 된다.

해당 요청이 끝나고, 다른 페이지로 이동하게 되면, 이 모든 프로세스가 반복된다.

 

가장 중요한 것은, 중요한 유저 정보는 모두 서버에 있다는 것

유저가 가지고 있는 것은 세션 ID 뿐

쿠키는 그저 세션 ID를 전달하기 위한, 매개체일 뿐이다.

세션을 이용해서 IOS, Android 앱을 만들 수 있지만, 브라우저에만 존재하기 때문에 쿠키는 사용할 수 없다.

⇒ 바로 이 경우, '토큰(token)'을 사용한다.(서버에 '토큰'을 보내는 것)

Token

토큰은 그냥 이상하게 생긴 String

해당 토큰을 서버에 보내고, 서버는 세션 DB에서 해당 토큰과 일치하는 유저를 찾는다.

세션에 대해 기억해야할 것은, 현재 로그인한 유저들의 모든 세션 ID를 DB에 저장해야한다는 것이다.

즉 요청이 들어올 때마다, 서버는 쿠키를 받아서, 세션 ID를 보고 세션 ID와 일치하는 유저를 찾아야하고, 다음 작업을 수행할 수 있다.

⇒ 요청이 있을 때마다 DB를 찾아야한다는 것.

즉, 유저가 늘어감에 따라 DB 리소스가 더 필요한 것이다.

바로 이때, JWT가 등장!

JWT

토큰 형식.

JWT로 유저 인증을 처리하면, 세션 DB를 가질 필요가 없고, 서버는 유저 인증을 한다고 많은 일을 처리하지 않아도 된다.

  • 토큰은 그냥 이상하게 생긴 텍스트이다.
    서버에서 받아서 요청할 때마다 보내야한다.

로그인 예시를 통해 JWT와 세션의 차이점

유저명 Nico가 로그인을 하려면 유저명과 비밀번호를 서버에 보내야한다.(여기까진 차이점 없음)

유저명과 비밀번호가 일치하다면, 서버는 DB에 무언가를 생성하지 않는다.

대신, 서버는 유저의 ID를 가져다가(예를 들면) 사인 알고리즘을 이용해서 '사인'을 할 것이다.

그리고 해당 '사인된 정보'를 String 형태로 클라이어트에게 보냄.

JWT는 보통 세션 ID보다 훨씬 길다.

왜냐하면 쿠키는 또한 공간 제약이 존재하기 때문이지만 JWT는 제약이 없어서 엄청 길어도 된다.

JWT의 경우 세션과 달리 로그인을 할때, DB를 건드리는 대신, 정보를 사인하고 전달하는 것이 전부이다.

 

서버에 요청을 보내려면, 세션 ID와 비슷하게 해당 '사인된 정보'혹은 토큰을 서버에 보내야한다.

서버는 토큰을 받으면 해당 사인이 유효한지 체크하고, 이는 토큰을 조작했는지 체크하는 것이다.

토큰이 유효하다면, 서버는 클라이언트를 유저로 인증할 것이다.

바로 이것이 세션과 JWT의 가장 큰 차이점!

 

Session

세션에서는 그냥 서버에서 세션 ID만 주면된다.

세션에 대한 모든 정보는 세션 DB에 저장되어있다.

클라이언트가 페이지를 요청하면, 서버는 세션 ID를 DB에서 찾으면 되는 것이다.

JWT

JWT에선 서버는 유저를 인증하는데 필요한 정보를 토큰에 저장

그리고 해당 토큰을 유저에게 준다.

페이지를 요청하면, 서버는 해당 토큰이 유효한지만 검증하면 된다.

⇒ DB를 거칠 필요가 없다!

이때 염두해야할 것은 JWT는 암호화되지 않았다는 것.

암호화되었다면 아무도 읽을 수 없고, 이해할 수 없다.

JWT의 경우, 누구나 열어서 해당 컨텐츠를 볼 수 있다.

즉, 비밀정보를 JWT 안에 둬서는 안된다.

 

JWT의 핵심은 토큰을 사인하고, 이를 통해 유효한지 검증한다는 것이다.

 

세션 vs JWT 장단점

세션 - 장점

세션을 사용하면, 서버는 로그인된 유저의 모든 정보를 저장한다.

해당 정보를 이용하면, 새로운 기능들을 추가할 수 있게 된다.

ex) 특정 유저를 쫓아내고 싶을 때(로그아웃 시키고 싶을 때), 그때 그냥 세션을 삭제해버리면 된다.

혹은 인스타그램처럼 사용, 로그인된 모든 디바이스를 보여주는 데, 원하지 않는 디바이스에서 강제로 로그아웃을 할 수 있다.

넷플릭스처럼 계정 공유 숫자를 제한할 수 있다. 현재 몇명이 로그인을 했고, 시청하는 지 알 수 있다.

이 모든 기능이 가능한 것은, 서버가 누가 로그인 했는지 저장했고, 세션 DB가 있기 때문.

세션 - 단점

위와 같은 장점을 유지하기위해 유저에 대해 다 알고싶다면, 이를 위해선 DB를 사고, 유지해야한다.

게다가 유저가 늘어나면 날수록, DB도 커져야 한다.

이를 위한 DB로는 주로 Redis를 사용한다.

REDIS

해당 목적을 수행하기 위한, 빠르고, 저렴한 DB

 

JWT - 장점

JWT를 사용하면, 생성된 토큰을 추적하지 않는다. 서버가 아는 것은 토큰이 유효한가 여부일 뿐이다.

JWT에서는 DB를 따로 살 필요가 없다.

JWT-단점

하지만 동시에 강제 로그아웃 등의 기능을 사용할 수 없다.

해당 토큰이 만료되기 전까지는 유효하기 때문

 

그렇다고 JWT가 별로인것은 아니다.

데이터를 사인하고, 유저에게 보내고, 해당 데이터를 돌려받을 때, 유효성을 검증할 수 있다. DB없이 모든 것이 가능

한구에서 코로나 때문에 하는 QR 체크인은, 바로 JWT가 들어간 QR 코드다!!(처음알게되었다)

JWT는 사용사례가 많다.

그중 하나가 세션이나 DB 없이 유저를 인증하는 것이고, JWT 인증의 제약만 잘 알아두면 된다.

하지만 유저가 늘어나고, 유저 계정을 좀 더 잘 관리하고 싶다면, 그때는 세션이 낫지 않을까?

정리

쿠키: 그냥 옮기는 시스템 또는 매개체

토큰: 서버가 기억하는 이상하게 생긴 텍스트으로, ID 카드 처럼 서버에게 보여줘야하는 것

JWT: 정보를 갖고 있는 토큰, DB 없이 검증 가능, 유저 인증을 위해 JWT 혹은 세션을 사용할 수 있다.

 

궁금증

JWT는 원격으로 로그아웃 할 수 없다고 하는데, 로그아웃할 장치의 토큰을 무효한 것으로 판단하는 방식이 불가능한 이유는?

세션DB를 통해 해당 유저를 Find하여 강제 세션아웃 시킬수 있기때문에 원격이 된다고 하는 것으로 추측된다.

JWT의 경우에는 DB나 서버의 자원에서 갖고있는 부분이 아니기때문에, 일반적으로 Decode하여 유저인지 인증하는 용도로 사용.

JWT를 Expire(만료) 시키기 위해서는 Client에서 요청을 보내야만 JWT를 만료 할 수 있다.

순수하게 JWT 자체로 계정이 3명이니, 원격 로그아웃을 해주세요. 라는 가정을 하신다면, JWT를 발급받은 ID들이 DB혹은 서버의 메모리에 저장되어야 한다.

그렇게 될 경우 JWT의 장점인 서버 자원을 사용하지 않는다에 위배된다.

해당 방식은 세션과 동일해 지는 부분.

JWT자체에 관한 정보를 Server에선 갖고 있지 않으므로, 요청이 오기전까지 Expire할 수 없다.

만약 원격 Expire를 한다면, 요청이 올때까지 기다렸다가 해당 JWT를 Decode한 이후, UserID를 확인하여 Expire하는 Logic을 구현하시면 될 것 같다.

흔치 않는 경우이기때문에 해당 설명에서는 원격 로그아웃이 불가능하다 라고 하시는것 같다.

반응형