•
인증은 신원미상의 사용자가 누구인가를 가려내는 것이다.
•
인가는 인증 작업 이후에 이뤄지는 작업으로 이미 인증된 사용자가 어떠한 자원에 접근하고자 할때 접근 권한을 확인하는 과정이다.
•
HTTP은 무상태성을 가지므로 서버는 클라이언트의 상태를 저장하지 않으므로 이 요청이 시작인지, 중간인지 알 방법이 없다.
◦
클라이언트가 이미 인증 과정을 거쳤음에도 불구하고 다음 HTTP 통신에서 서버는 이 클라이언트가 인증을 했는지 확인할 방법이 없다는 의미다.
•
그렇다고 모든 HTTP 요청에 인증 과정을 추가하는 것은 정말 불합리하고 융통성없는 행위일 것이다.
◦
사용자 경험 관점에서도 좋지 않지만 네트워크 비용에서도 문제가 많을 것이다.
•
이런 HTTP를 통해 통신할때, 서버는 어떤 방식으로 인증된 사용자를 확인하고 인가 과정을 처리할까? 대표적으로 세션과 토큰이 존재한다.
세션 기반 인증
•
세션 기반 인증은 사용자의 인증 정보를 서버가 세션에 저장해두는 것을 의미한다.
◦
이때 세션에는
•
사용자가 인증 과정을 수행하면 해당 인증 정보를 서버가 세션 저장소에 저장해두고 사용자에게는 저장된 세션 정보의 식별자인 SessionId를 발급한다.
•
발급된 SessionId는 클라이언트에게 전달되어 이후 요청 시 헤더로 제공되어 내가 인증된 사용자임을 증명하기 위해 사용된다.
•
서버는 각 요청에 대해서 SessionId가 헤더에 존재하는지 확인 후, 존재한다면 이를 세션 저장소에서 조회해 해당 유저의 인증 정보(닉네임, 식별자 등)을 가져와 요청의 주체를 정한다.
토큰 기반 인증
•
토큰 기반 인증은 인증 정보인 토큰을 클라이언트가 가지고 있는 방식이다. 이때 인증 정보가 토큰의 형태로 브라우저의 로컬 저장소나 쿠키에 저장된다.
◦
토큰의 종류에 따라 다르지만 JWT의 경우, 디지털 서명을 통해 토큰의 내용이 위변조되었는지 확인할 수 있다.
•
사용자가 인증 과정을 수행하면 해당 인증 정보를 토대로 서버는 토큰을 만들어 클라이언트에게 전달한다.
•
이후 생성된 토큰을 클라이언트가 요청을 수행할 때마다 Autorization 헤더를 통해 보낸다.
•
이 토큰을 수신한 서버는 해당 토큰이 위변조되었거나 만료되었는지 확인한 후, 토큰에 담겨있는 인증 정보를 토대로 요청의 주체를 정한다.
차이점
•
크기
◦
단순히봐도 사용자 인증 정보까지 담고 있는 토큰이 세션 식별자만 가지고 있으면 되는 세션 기반보다 더 클 것이다.
•
보안
◦
세션의 경우, 모든 인증 정보를 서버가 저장하고 관리하기 때문에 보안 측면에서 조금 더 유리하다.
▪
만약 SessionId가 탈취되어도 서버 측에서 해당 세션을 만료시켜버리면 그만이다.
▪
서버에서 관리하므로 어떤 정보를 저장해도 상관없다. 다만 네트워크 비용을 생각해서 적절히 그 양을 조절하는 것이 좋다.
◦
토큰의 경우, 서버와는 상관없이 클라이언트 측에서 관리되고 모든 인증 정보를 가지고 있다. 따라서 탈취된다면 만료기한 전까지 피해가 발생할 수 밖에 없다.
▪
또한 JWT 특성상 토큰에 담긴 Payload가 별도로 암호화되어있지 않으므로 누구나 확인할 수 있다.
▪
이 때문에 Payload에 중요한 데이터는 담을 수 없다.
•
서버의 비용
◦
세션 기반 인증 방식은 서버가 세션 데이터를 직접 저장하고 관리하므로 세션 데이터의 양이 많아지면 많아질수록 서버의 부담이 증가하게 된다.
◦
토큰 기반 인증 방식의 경우, 페이로드 값을 토대로 사용자를 식별하기만 하면 되므로 데이터의 양에 구애받지 않는다.
•
확장성
◦
크기와 보안에서 세션이 토큰보다 나음에도 토큰이 사용되는 이유는 확장성에서 오는 차이 때문이다.
◦
일반적으로 웹 어플리케이션 서버의 확장 방식은 수평 확장이므로 수평 확장이 발생했을 때, 세션이 기존 서버의 로컬에서 관리되고 있었다면 인증을 했음에도 재인증이 필요하게 될 것이다.
⇒ Sticky Session, Session Clustering 등의 방법을 사용해야 한다.
◦
토큰 기반 방식의 경우, 이 부분에서 자유롭다. 이 덕분에 토큰의 경우, HTTP의 무상태성을 그대로 활용할 수 있고 확장성에서 뛰어나다.