2 minute read

1. HTTP통신

서버-클라이언트는 HTTP프로토콜을 사용하여 통신하는데, 이 프로토콜의 특징은 무상태성(stateless)입니다. 무상태성이라는 말은 어렵게 들리지만, 저장하는 상태(state)가 없다는 것, 그러니까, 모든 리퀘스트는 독립적으로 다뤄지며, 리퀘스트가 끝나면 서버는 클라이언트가 누구인지 잊어버리게 된다는 것입니다. 문제는 우리가 웹을 사용할 때 서버로 하여금 우리를 기억하게 할 필요가 있다는 것입니다. 그리고 이 때 사용하는 것이 세션과 쿠키입니다.

2. 세션 (session)

로그인을 예를 들어보겠습니다. 회원가입이 되어있는 상태라고 가정했을 때, 아이디와 비밀번호가 일치한다면 서버는 세션DB에 유저를 생성하게 됩니다. 이때 유저의 정보와 unique한 세션ID가 쿠키를 통해 브라우저로 들어와서 저장됩니다. 쿠키는 각 서비스(사이트) 마다 독립적으로 생성되는 것으로, 자동으로 서버로 전송되며, 클라이언트와 서버 사이에서 이동합니다. 그리고 이 쿠키 안에 세션아이디가 담겨있는 것입니다. 정리하자면, 쿠키는 세션아이디를 전달하기 위한 수단으로 쓰입니다.

여기서 몇가지 문제상황이 발생할 수 있는데,

첫번째 문제상황

  1. 현재 로그인한 유저들의 모든 세션 id를 Session DB에 저장해야합니다.
  2. 모든 요청이 들어올 때마다, 쿠키를 통해 session id를 체크한 후 session DB에서 일치하는 유저를 찾아야 합니다.
  3. 따라서 사용자와 요청의 개수가 많아지면 DB에 부담이 생깁니다.

두번째 문제상황

  1. 서버를 여러 개 둔 경우, 요청이 로드밸런서에 의해 각기 다른 서버로 전달될 수 있습니다.
  2. 두번째로 요청을 받은 서버는 session 정보가 없으므로(서버는 세션을 각각 관리합니다), 로그인을 재요청하는 경우가 생기게 됩니다.
  3. 세션 스토리지를 사용하여 세션을 한꺼번에 관리하는 방법도 있으나, 이 경우도 사용자가 많아지는 경우 DB에 부담이 생깁니다.

3. JWT (JSON WEB TOKEN)

위의 상황을 해결하고자 할 때 사용할 수 있는 것이 JWT입니다. JWT를 활용하는 경우에, 로그인을 성공적으로 하면, 데이터베이스에 아무것도 저장하지 않고 아이디를 암호화 한 스트링값을 쿠키를 통해 보내줍니다. 디비를 건드리는 대신 정보를 sign하고 전달하는 것입니다. 앞으로의 인증은 이 JWT를 통해서 이뤄지게 됩니다. 사용자가 JWT토큰을 리퀘스트로 보내면, 서버는 서버가 가진 키를 사용하여 토큰이 유효한지 검증한다. 서버들이 검증 키값을 공유하기 때문에, 위의 세션과 같은 문제상황이 발생하지 않게 됩니다.

그런데 여기서도 문제상황이 발생할 수 있으니, 바로 토큰이 탈취되는 경우입니다. 이 경우를 위해 토큰에는 유효시간이 있는데, 이 때 사용하는 것이 refresh token입니다. 서버는 access token과 refesh token을 함께 클라이언트로 보내며, refresh token만 유효시간과 함께 저장합니다. access token이 만료되면, refresh token으로 db를 확인한 후 갱신된 access token을 발급해줍니다.

4. 결론

JWT 토큰으로 상태관리를 하는 경우, session DB가 필요없습니다. 토큰 관리를 잘 해야한다는 보안상의 이슈가 있습니다.

5. 사용 예

sessionID : 서비스에서 세션을 끊거나 하는 식으로 유저들의 사용을 제한할 수 있습니다. (넷플릭스 공용아이디 같은 경우) JWT토큰은 토큰이 유효한지만 검사하고 사용자를 추적하지 않기 떄문에 강제로그아웃과 같은 기능을 할 수 없습니다.

JWT : 코로나 QR코드인증과 같은 경우가 해당됩니다. 세션이나 db없이 주어진 시간동안 유저를 인증할 수 있게 해줍니다.

6. 더 공부해볼 것

  • SSL/TLS 적용
  • Refresh Token과 관련된 보안 이슈
  • Sliding Session

참고

노마드 코더 - 세션 vs 토큰 vs 쿠키? 기초 개념 잡아드림

우아한테크코스 10분 테코톡 - 토니의 인증과 인가


광고


Comments