서버는 쿠키를 이용해서 브라우저에 데이터를 넣을 수 있다.
사이트에 방문하면 브라우저는 서버에 요청을 보낸다.
웹사이트 방문 → 브라우저는 서버에 요청 → 서버는 이에 반응 → 응답에는 모든 데이터와 내가 찾던 페이지의 정보가 있음 → 그곳에는 브라우저에 저장하고자 하는 쿠키가 있을 수 있음 → 브라우저에 쿠키를 저장 → 해당 웹사이트에 방문할 때마다 브라우저는 해당 쿠키도 요청과 함께 보냄
쿠키는 도메인에 따라 제한이 된다.
쿠키는 유효기한이 있다.
웹사이트의 언어설정을 바꾸면 서버는 쿠키를 주고 설정한 언어를 저장한다.
다음 해당 웹사이트에 방문할 때, 쿠키는 요청과 함께 서버로 보내지고, 서버는 쿠키가 기억해둔 언어설정으로 바뀐 페이지를 제공한다.
HTTP 웹 사이트를 이용할 때 쓰는 프로토콜.
서버로 가는 모든 요청이 이전 리퀘스트와 독립적으로 다루어진다.
요청끼리 연결이 없다 → 메모리가 없다는 의미이다.
요청할때마다 우리가 누군지 알려줘야 한다.
→ 이를 확인하는 방법이 Session 이다.
웹 사이트의 여러 페이지에 걸쳐 사용되는 사용자 정보를 저장하는 방법을 의미한다.사용자가 브라우저를 닫아 서버와의 연결을 끝내는 시점까지를 세션이라고 한다.
'Bumsu'라는 유저명이 있고, 로그인을 하고 싶다면 유저명과 비밀번호를 서버에 보낸다.
비밀번호가 맞다면 서버는 세션 DB에 'Bumsu'라는 유저를 생성한다.
해당 세션에는 별도의 ID가 있고, 해당 세션 ID는 쿠키를 통해 브러우저로 돌아오고 저장된다.
따라서, 같은 웹사이트의 다른 페이지로 이동하면, 브라우저는 세션ID를 갖고 있는 쿠키를 서버에 보낸다.
쿠키는 자동을 보내지기 때문에 서버는 들어오는 쿠키를 보고 세션ID와 함께 들어오는 쿠키를 확인한다.
이때까지도 서버는 우리가 누구인지 알지 못한다.
세션ID가 있는 쿠키를 지닌 요청이 있다는 것만 알뿐이다.
해당 세션ID를 가지고 세션DB를 확인할 것이고, 거기서 해당ID는 유저명 Bumsu의 것이라는 것을 알게되고 그제서야 서버는 우리가 누구인지 알게 된다. 그리고 그때 "환영해요 Bumsu" 라는 메세지를 띄울 수 있을 것이다.
기억해야할 것은, 중요한 유저 정보는 모두 서버에 있다는 것이다.
유저가 갖고 있는 것은 세션ID 뿐이다.
쿠키는 그저 세션ID를 전달하기 위한 매개체일 뿐이다.
세션을 이용해 IOS, Android 맵을 만들 수 있지만 쿠키는 사용할 수 없다.
쿠키는 브라우저에만 있다. (네이티브앱에는 없음)
바로 이 경우, '토큰(token)'을 사용해 서버에 '토큰'을 보내는 것이다.
토큰은 그냥 이상하게 생긴 string 이다.
해당 토큰을 서버에 보내고, 서버는 세션DB에서 해당 토큰과 일치하는 유저를 찾는다.
세션에 대해서 기억해야할 것은 현재 로그인한 유저들의 모든 세션ID를 DB에 저장해야한다는 것이다.
즉, 요청이 들어올 때 마다 서버는 쿠키를 받아서 세션ID를 보고 세션ID와 일치하는 유저를 찾아야하고, 그제서야 다음 작업을 수행할 수 있다.
유저가 늘어남에 따라 DB 리소스가 더 필요하다.
이때 JWT가 등장한다.
JWT는 토큰 형식이다.
JWT로 유저 인증을 처리하면 세션DB를 갖을 필요가 없고 서버는 유저 인증한다고 많은 일을 하지 않아도 된다. 토큰은 그냥 이상하게 생긴 텍스트이다.
서버에서 받아서 요청할때마다 보내야하는 것이다.
유저명 Bumsu가 로그인을 하려면,
유저명과 비밀번호를 서버에 보내야한다. (여기까지는 동일)
유저명과 비밀번호가 맞다면, 서버는 DB에 뭔가를 생성하지 않는다.
대신 서버는 유저의 ID를 가져다가 (예로 들면) 사인 알고리즘을 이용해서 '사인'을 할것이다.
그리고 해당 '사인된 정보'를 string 형태로 보낼것이다.
JWT는 보통 세션ID보다 훨씬 길다.
쿠키는 공간 제약이 있지만 JWT는 제약이 없어서 길어도 된다.
동일하게 로그인을 했는데 DB를 건드리는 대신, 정보를 사인하고 전달하는 것이 전부이다.
이제 서버에 요청을 보내려면, 세션ID와 비슷하게 해당 '사인된 정보' 혹은 토큰을 서버에 보내야한다.
서버는 토큰을 받으면, 해당 사인이 유효한지 체크하고 → 이는 토큰을 조작했는지 체크하는 것이다.
토큰이 유효하다면, 서버는 우리를 유저로 인증할 것이다.
바로 이것이 세션과 JWT의 가장 큰 차이점이다.
세션에서는 그냥 세션ID만 주면 된다.
세션에 대한 모든 정보는 세션 DB에 저장되어 있다.
페이지를 요청하면, 서버는 세션ID를 DB에서 찾으면 되는 것이다.
JWT에서는 서버는 유저를 인증하는데 필요한 정보를 토큰에 저장한다.
그리고선 해당 토큰을 우리에게 준다.
페이지를 요청하면, 서버는 해당 토큰이 유효한지만 검증하면 되는 것이다.
DB를 거칠 필요가 없다.
중요한 것은, JWT는 암호화 되어 있지 않다
'암호화' 되었다면 아무도 읽을 수 없고 이해할 수 없다.
JWT의 경우 누구나 열어서 해당 컨텐츠를 볼 수 있다.
비밀정보를 JWT안에 둬서는 안된다.
핵심은, 토큰을 사인하고, 이를 통해 유효한지 검증한다는 것이다.
세션을 사용하면 서버는 로그인된 유저의 모든 정보를 저장한다.
해당 정보를 이용하면, 새로운 기능들을 추가할 수 있게 된다.
예를 들면, 특정 유저를 쫓아내고 싶을 때, 그때 그냥 세션을 삭제해버리면 된다.
이 모든 기능이 서버가 누가 로그인했는지 저장하고, 세션DB가 있기 떄문이다.
이렇게 다 알고싶다면 이를 위해선 DB를 사고 유지해야한다.
게다가 유저가 늘어나면 늘어날수록 DB도 커져야한다.
이를 위한 DB로는 주로 Redis를 사용한다.
Redis는 해당 목적을 수행하기 위한 빠르고 저렴한 DB이다.
JWT를 사용하면, 생성된 토큰을 추적하지 않는다.
서버가 아는 것은 토큰이 유효한가 여부일 뿐이다.
JWT에선 DB를 따로 살 필요가 없다.
하지만 동시에 아까 말한 그런 기능 (강제 로그아웃)을 할 수 없다.
왜냐하면 해당 토큰이 만료되기 전까지는 유효하기 때문이다.
JWT는 데이터를 사인하고 유저에게 보내고 해당 데이터를 돌려받을 때, 유효성을 검증할 수 있다.
DB 없이 모든 것이 가능하다.
예시로, 한국에서 코로나 때문에 하는 QR체크인은 바로 JWT가 들어간 QR코드이다.
JWT를 이용하는 사례 중 하나는 세션이나 DB없이 유저를 인증하는 것이다.
서비스가 커지고 유저 계정을 좀더 잘 관리하고 싶다면 그때 세션으로 옮기면 좋을듯하다.
쿠키 = 그냥 옮기는 시스템, 매개체
토큰 = 서버가 기억하는 이상하게 생긴 텍스트, ID카드 처럼 서버에게 보여줘야하는 것이다.
JWT = 정보를 갖고 있는 토큰, DB없이 검증할 수 있다.
유저 인증을 위해서 JWT 혹은 세션을 사용할 수 있다.