인증 방식 종류
JWT에 대해 공부하기 전, 우선적으로 인증 방식 종류에 대해 알아보겠다. 크게 2가지 인증 방식이 있다.
- Session 기반 인증
- Token 기반 인증
2가지 방식의 차이는 '인증 확인 증거를 어디에 저장하느냐' 에 있다. Session 기반은 DB서버에, Token 기반은 Client측에 저장한다. 우리가 사용할 JWT는 Token 기반 인증 방법중 하나이다.
Session 기반 인증
사용자의 정보를 서버측에 기억하고 있는 인증 방식으로, 이를 위해 Session과 Cookie가 사용된다.
사용자가 로그인을 하면, 해당 인증 정보를 서버의 세션 저장소에 저장하고, 사용자에게는 저장된 세션 정보의 식별자인 Sessin ID를 발급한다. 발급된 Session ID는 브라우저에 Cookie 형태로 저장되지만, 실제 인증 정보는 서버에 저장된다.
브라우저는 인증 절차를 마친 이후의 요청마다 HTTP Cookie 헤더에 Session ID를 함께 서버로 전송한다. 서버는 요청을 전달받고, Session ID에 해당하는 세션 정보가 세션 저장소에 존재한다면 해당 사용자를 인증된 사용자로 판단한다.
장점
- 정보가 서버에 저장되기 때문에 Token 기반 인증에 비해 위변조 혹은 손상 우려가 없다.
단점
- 서비스의 규모가 커질수록 세션 저장소에 쌓이는 데이터가 많이지기에 서버에 무리를 줄 수 있다.
- 서비스의 규모가 커져서 사용자가 늘어나게 되면, 그에 늘어난 트래픽을 처리하기 위한 조치가 필요하다.
Token 기반 인증
많은 웹 어플리케이션에서 사용하는 방식으로 JWT (JSON Web Token)을 사용한다. Session 기반 인증 방식과 가장 큰 차이점은 유저의 정보가 서버에 저장되지 않는다는 점이다.
세션 기반 인증이 인증 정보를 서버에 저장하는 방식이라면, 토큰 기반 인증은 인증 정보를 유저(클라이언트)가 직접 들고 있는 방식이다. 이때 인증 정보가 토큰의 형태로 브라우저의 로컬 스토리지(or 쿠키)에 저장된다. 토큰의 종류에 따라 다르겠지만, 대표적인 토큰인 JWT의 경우 디지털 서명이 존재해 내용이 위번조 되었는지 서버측에서 확인할 수 있다.
토큰 기반 인증에서는 사용자가 갖고 있는 토큰을 HTTP의 Authorization 헤더에 실어 보낸다. 이 헤더를 수신한 서버는 토큰이 위변조 되었거나, 만료 시간이 지나지 않은지 확인한 후 토큰에 담겨있는 사용자 인증 정보를 확인하여 사용자를 Authorization한다.
장점
- JWT는 클라이어트 측에서 저장하므로 서버 메모리 또는 DB에 부담을 주지 않고, 서버는 완전히 Stateless로 남게된다.
- 클라이언트와 서버가 독립적으로 행동하기에 확장성을 확보할 수 있다.
단점
- JWT가 브라우저에 그대로 노출되어있기에 위변조나 손상의 위험이 크다 (XSS 공격)
- 한번 발급된 토큰은 임의로 만료시킬 수 없기에 해커에게 탈취되었다면, 해커는 토큰이 만료될때까지 계속 공격할 수 있다.
정리
* 안정성과 보안
Session 인증 방식의 경우 모든 인증 정보를 서버에서 관리하기 때문에 보안 측면에서 Token 인증 방식보다 유리하다. Session 인증 방식의 경우 만일 Session ID가 해커에게 탈취되어도, 서버측에서 해당 Session을 무효처리하면 정보를 탈취당할일이 없다.
하지만, Token 인증 방식의 경우는 앞서 말했듯이 그렇게 할 수 없다. Token을 임의로 만료시킬 수 없기에 탈취당한 Token이 만료되기 전까지는 속수무책 당할 수 밖에 없다. 또한 JWT 특성상 Token에 실린 Payload가 별도로 암호화 되어있지 않으므로, 누구나 내용을 쉽게 확인할 수 있다. 따라서 Payload에는 민감한 데이터는 넣어서는 안된다.
* 확장성
앞서 말한 보안상의 문제로 Token 기반 인증 방식이 더 취약하지만 해당 방식을 선호하는 이유는 확장성때문이다.
일반적으로 웹 어플리케이션의 서버 확장 방식은 수평 확장을 사용한다. 즉, 여러대의 서버가 요청을 처리한다. 이러한 확장 방식에서 Session 기반 인증방식은 Session 불일치 문제를 겪게 되는데, 이를 해결하기 위해서는 Sticky Session, Session Clustering, Session Storage 외부 분리 등과 같은 별도의 작업을 해주어야한다.
하지만, Token 기반 인증 방식의 경우 서버가 직접 인증 방식을 저장하지 않고, 클라이언트가 저장하는 방식이기에 이러한 Session 불일치 문제로부터 자유롭다. 이러한 특징으로 Token 기반 인증 방식은 HTTP의 Stateless를 그대로 활용할 수 있기에 높은 확장성을 갖는다.
* 서버의 부담
앞서 말한 확장성에서 이어지는 내용이다. Session 기반 인증 방식은 서비스가 Session 데이터를 직접 저장하고, 관리한다. 따라서 Session 데이터의 양이 많이지게 되면 서버의 부담이 증가하게 된다.
하지만, Token 기반 인증 방식은 클라이언트가 인증 데이터를 직접 가지고 있기에, 유저의 수가 증가해도 서버의 부담이 증가하지 않는다.
참고:
https://hudi.blog/session-based-auth-vs-token-based-auth/
https://jins-dev.tistory.com/entry/Session-%EA%B8%B0%EB%B0%98-%EC%9D%B8%EC%A6%9D%EA%B3%BC-Token-%EA%B8%B0%EB%B0%98-%EC%9D%B8%EC%A6%9D
https://velog.io/@arthur/%EC%84%B8%EC%85%98-%EC%9D%B8%EC%A6%9D-%EB%B0%A9%EC%8B%9D-vs-%ED%86%A0%ED%81%B0-%EC%9D%B8%EC%A6%9D-%EB%B0%A9%EC%8B%9D