쿠키(Cookies), 세션(Sessions), 토큰(Token), JWT의 기본개념

아카시아·2021년 10월 4일
0

Auth(인증)을 통해 서비스는 유저를 검증할 수 있다. 이 Auth(인증)을 만들려고 해봤다면 쿠키, 세션, 토큰, JWT를 한번쯤은 들어봤을 것이다.

  • 쿠키(Cookies)

  1. 서버의 응답에는 모든 데이터와 브라우저에서 찾던 페이지 정보가 있을텐데 그곳에는 브라우저에 저장하고자 하는 데이터나 정보가 있을 수 있다. 그 원하는 데이터나 정보를 쿠키를 이용해 서버는 유저의 브라우저에 데이터를 넣을 수 있다.

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

  3. 쿠키는 도메인에 따라 제한이 된다. (예를 들어, 유튜브가 준 쿠키는 유튜브에만 보내지게 된다.)

  4. 쿠키는 유효기간이 있다. (서버가 정한 기간에 따라 유효하다.)

  5. 인증뿐만 아니라 여러가지 정보를 저장 가능하다. (예를 들어, 웹사이트 언어설정을 바꾸면 서버는 쿠키를 주고 내가 선택한 언어를 저장하게 된다. 따라서 다음에 내가 해당 웹사이트에 방문할 때 쿠키는 요청과 함께 서버로 보내지고 덕분에 서버는 쿠키가 기억해둔 언어설정의 페이지를 제공한다.)

HTTP는 기본적으로 stateless상태 즉, 서버로 가는 모든 요청이 이전 리퀘스트와 독립적으로 다뤄진다. 그래서 요청이 끝나면 서버는 유저가 누군지 잊어버리게 된다. 따라서 요청할 때마다 우리가 누군지 알려줘야 한다. 이를 하는 방법 중에 세션과 토큰이 있다.

  • 세션(Sessions) 과 토큰(Token)

  1. 세션이 동작하는 과정 (유저명이 'AKACIA'인 사람이 로그인을 한다고 치자.)
    : 로그인 할 때 유저명과 비번을 서버에 보냄 -> 유저명과 비번이 맞으면 서버는 세션DB에 'AKACIA'라는 유저를 생성 -> 해당 세션에는 별도의 ID가 있어서 그 해당 세션ID는 쿠키를 통해 브라우저로 돌아오고 저장됨 (쿠키는 자동으로 보내지기 때문에 같은 웹사이트의 다른 페이지로 이동하면 브라우저는 세션ID를 갖고있는 쿠키를 서버에 보냄) -> 서버는 들어오는 쿠키를 보고 세션ID와 함께오는 쿠키를 확인하게 됨 (이때, 아직까지도 서버는 우리가 누군지 모르고 세션ID가 있는 쿠키를 지닌 요청이 있다는 것만 알 뿐이다.) -> 서버는 해당 세션ID를 가지고 세션DB를 확인할 것이고 거기서 해당 ID는 'AKACIA'라는 것을 알게되고 그제서야 서버는 우리가 누군지 알게됨 -> 해당 요청이 끝나고 다른 페이지로 이동하게 되면 이 모든 프로세스가 반복됨 (중요한 유저정보는 모두 서버에 있고 유저가 갖고있는 것은 세션ID뿐이다.)

  2. 쿠키는 그저 세션ID를 전달하기 위한 매개체일 뿐이고 세션을 이용해 iOS, Android앱을 만들 수 있지만 쿠키는 사용할 수 없다. (쿠키는 브라우저에만 있고 네이티브 앱에는 없음.) 이 경우에 '토큰'을 사용해 서버에 '토큰'을 보낸다.

  3. 세션은 요청이 있을때마다 DB를 참고해야해서 현재 로그인한 유저들의 모든 세션ID를 DB에 저장해야한다. 즉, 유저가 늘어남에 따라 DB리소스가 더 필요하다. 이런 불편함을 해소하기 위해 'JWT(JSON Web Token)'가 등장하게 된다.

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

  • JWT

  1. JWT가 동작하는 과정
    : 유저명 'AKACIA'가 로그인 하려면 유저명과 비번을 서버에 보냄 -> 유저명과 비번이 맞다면 서버는 DB에 뭔가를 생성하지 않고 서버는 유저의 ID를 가져다가 사인 알고리즘을 통해 '사인'을 하고 해당 '사인된 정보'를 String 형태로 유저에게 보냄 (쿠키는 공간제약이 있으나 JWT는 제약이 없어 길이가 길어도 되고 세션과 동일하게 로그인 했는데 DB를 건드리는 대신 정보를 사인하고 전달하는 것이 다이다.) -> 서버에 요청을 보내려면 세션ID와 비슷하게 해당 '사인된 정보' 혹은 '토큰'을 서버에 보내야함 -> 서버는 토큰을 받으면 해당 사인이 유효한지 체크함 (이는 토큰을 조작했는지 체크하는것) -> 토큰이 유효하다면 서버는 우리를 유저로 인증하게됨

  2. 세션과 JWT의 차이점

  • 세션 : 서버는 그냥 세션ID만 주면되고 세션에 대한 모든 정보는 세션DB에 저장되어있어서 페이지를 요청하면 서버는 세션ID를 DB에서 찾으면됨.

  • JWT : 서버는 유저를 인증하는데 필요한 정보를 토큰에 저장한다. 그리고선 해당 토큰을 우리에게 준다. 페이지를 요청하면 서버는 DB를 거칠 필요없이 해당 토큰이 유효한지만 검증하면 된다. 다만 JWT는 암호화되지 않는다. (암호화되어있다면 아무도 읽을 수 없고 이해할 수 없음) 따라서 누구나 열어서 해당 컨텐츠를 볼 수 있기때문에 비밀번호등을 JWT안에 둬서는 안된다.

  • 세션과 JWT의 장점과 단점

  • 세션 : 서버는 로그인된 유저의 모든 정보를 저장해서 해당 정보를 이용하면 새로운 기능들을 추가할 수 있게된다. (예를들어, 특정 유저를 삭제하고 싶을 때 그냥 세션을 삭제해버리면 된다. 혹은 인스타그램처럼 로그인된 모든 디바이스를 보여주는데 원치않는 디바이스에서 강제로 로그아웃할 수 있다. 아니면 넷플릭스처럼 계정 공유숫자를 제한할 수 있고 현재 로그인을 몇명이 했고 시청했는지 알 수 있다.) -> 이 모든 기능이 가능한 것은 서버가 누가 로그인했는지 저장하고 세션DB가 있기 때문이다. 따라서 유저가 늘어남에따라 DB도 커져야한다. (이를 위한 DB로 해당 목적을 수행하기위한 빠르고 저렴한 DB인 'Redis'를 많이 사용한다.)

  • JWT : 생성된 토큰을 추적하지 않고 서버가 아는 것은 토큰이 유효한가여부일 뿐이어서 DB를 따로 살 필요가 없다. 하지만 해당 토큰이 만료되기전까진 유효하니까 강제로그아웃같은 기능을 할 순 없다. (우리나라에서 코로나때문에 하는 QR체크인은 JWT가 들어간 QR코드이다.) 또한 JWT는 세션이나 DB없이 유저를 인증하는 것이 그 중 하나이며 사용사례가 많다. (JWT인증의 제약만 잘 알아두면 됨.) 그러나 JWT를 사용하다가 서비스가 커지면서 로그인관리기능이 추가된다면 JWT특성상 토큰정보에 의존한 구현이 클라이언트와 다른 서버에 되어있을 가능성이 커서 변경하는 것이 쉽지 않은 등의 이슈가 있기때문에 서비스가 더 커지고 유저계정을 좀 더 잘 관리하고 싶다면 그 때 세션으로 옮겨가는 것도 좋은 방향이 될 수 있다.

profile
낭만적인 개발자

0개의 댓글