이 글에서는 사용자를 인증하는데 사용되는 방식인 세션, JWT에 대해 다루려고 한다. 이를 위해 알아야 할 개념들을 먼저 소개하고 세션과 JWT 방식간의 장단점을 소개한다.
HTTP는 인터넷에서 데이터를 주고 받기 위한 서버/클라이언트 모델을 따르는 프로토콜이다. 클라이언트는 서버에게 요청을 보내고 서버는 해당 요청에 대한 응답을 제공하는데 이 때, 서버는 각 요청에 대해서 독립적으로 결과를 전송한다. 즉, 무상태성(Stateless)이라는 특징을 가진다. 따라서, 1개의 요청이 끝날 때마다 요청 상태 정보들은 남아있지 않게 된다. 그런데, 로그인의 경우 사용자가 로그인한 상태를 유지하고 있어야만 기능 수행이 자연스러운 기능들이 있다. 예를 들면, 게시판에 글을 수정 및 삭제 할 수 있는 버튼은 로그인하고 있고 해당 글 작성자 만이 볼 수 있어야 한다. 하지만, stateless한 상태에서 서버는 해당 사용자가 글 작성자인지, 심지어는 로그인을 한 상태인지 조차 알 수 없기 때문에 수정 및 삭제 버튼을 보여줄 수 없게 된다.
위의 문제를 해결하기 위해서 즉, 사용자의 상태를 전송하기 위해서 쿠키, 토큰을 사용한다.
쿠키는 브라우져(사용자)가 서버에 요청을 보낼 때 같이 전송하는 것으로 서버를 통해 브라우져에 설치되는 작은 기록 정보를 말한다. 서버는 쿠키에 담긴 정보를 토대로 요청을 보낸 사용자가 누구인지 식별할 수 있다. 쿠키는 키-밸류(key-value) 형식의 문자열이다.
토큰은 쿠키와 같이 사용자의 정보를 식별할 수 있게 같이 전달하는 스트링 정보이다.
사용자의 정보를 서버가 관리하는 방식으로, 서버는 사용자가 로그인을 하면 세션을 만들어 세션 DB에 저장하고 세션 ID값을 사용자의 쿠키에 담아서 사용자에게 전송해준다. 이 후 사용자는 요청을 보낼 때마다 해당 쿠키를 전송하면 서버는 쿠키에서 세션 ID값으로 세션 DB에 조회하여 어떤 사용자인지 식별할 수 있다.
2절에서 설명한 토큰과 같은 것으로 인증에 필요한 정보들을 암호화시킨 것이다. 쿠키 방식과 유사하게 HTTP 헤더에 토큰을 실어서 전송하고 이를 기반으로 서버는 해당 JWT가 조작되었는지 인증절차를 거치고 사용자를 식별할 수 있다.
JWT는 .(온점)을 구분자로 나누어지는 3가지 문자열의 조합으로 Header, Payload, Signature로 구분된다. Header는 정보를 암호화할 해싱 알고리즘과 토큰의 타입을 지정한다. Payload는 클라이언트의 id값, 유효 기간 등의 토큰에 담을 핵심 정보들을 담는다. Signature는 Header + Payload를 비밀키로 해싱하여 생성한다. Header와 Payload는 단순히 인코딩된 값이기 때문에 제 3자가 복호화 및 조작할 수 있지만 Signature는 서버 측에서 관리하는 비밀키가 유출되지 않는 한 복호화할 수 없다. 따라서 Signature는 토큰의 조작 여부를 확인하는데 사용된다.
https://tecoble.techcourse.co.kr/post/2021-05-22-cookie-session-jwt/