팀 프로젝트를 진행하면서 사용자 인증, 인가 기능 개발을 맡았다. 맡은 부분을 개발하면서 많은 고민을 하고 코드를 점진적으로 개선했다. 이 과정에서 한 고민과 경험을 공유하기 위해 글을 작성하게 됐다.
Session vs Token
첫 번째 만났던 문제는 사용자 인증 방식이었다.
사용자 인증 방식은 토큰 기반 방식과 세션 기반 방식이 있다. 이 중 어떤 방식으로 개발할지 고민했다. 현재 상황에 맞는 선택하기 위해 두 방식의 장단점을 이해하고 내 상황에 적절한 방식을 선택했다.
Session
세션 기반 방식의 흐름은 다음 그림과 같다.
세션 기반 방식은 사용자가 인증되면 사용자와 관련된 세션을 만들고, 세션 아이디를 반환해 준다. 이때 세션은 서버 메모리 또는 DB에 저장할 수 있다. 그 후 사용자는 세션 아이디를 이용해 자신을 인증한다.
Token
토큰 기반 방식의 흐름은 다음과 같다.
토큰 기반 방식은 사용자가 인증되면 서버만 알고 있는 비밀키를 이용해 토큰을 생성하고 반환해 준다. 그 후 사용자는 토큰을 이용해 자신을 증명한다.
Session vs Token
scalability
확장성 관점에서는 토큰 기반 방식이 유리하다.
세션 기반 방식은 인증 관련 자세한 정보를 서버에서 관리한다. 따라서 동시에 많은 사용자 접속하면 서버의 메모리가 부족해질 수 있고, 서버 부하가 심해져 서버가 죽을 수 있다.
하지만 토큰 기반 방식은 인증 관련 자세한 정보를 클라이언트에서 관리한다. 따라서 동시에 많은 사용자가 접속해도 서버를 동적으로 scale-out 시켜 대응할 수 있다. 또, 서버의 부하도 세션 방식과 비교하면 적다.
performance
성능도 토큰 기반 방식이 유리하다.
세션 기반 방식은 요청을 인증하기 위해 메모리 또는 데이터베이스와 소통해야 한다. 반면에 토큰 기반 방식은 비밀키를 이용해 토큰을 인증하기만 하면 된다.
세밀한 권한 제어
인증과 관련된 세밀한 제어는 세션 기반 방식이 유리하다.
세션 기반 방식은 인증 관련 자세한 정보를 서버에 저장하고 있다. 따라서 인증과 관련된 제어, 예를 들면 강제 로그아웃, 다중 로그인 제어를 할 수 있다. 하지만 토큰 기반의 방식은 인증 관련 자세한 정보를 클라이언트가 갖고 있어서 그러지 못한다.
나의 선택
우리 팀은 CGV 예매 API를 클론하고 있었다. CGV 예매 사이트는 순간적으로 트래픽이 증가할 수 있어서 scalability, performance가 세밀한 권한 제어보다 중요하다고 생각했다. 따라서 토큰 기반 방식을 선택했다.
Jwt 로그인 구현하기
우리 팀의 도메인 특성을 고려해 로그인 방식을 선택했고, 토큰 기반 방식 중 Jwt 방식을 선택했다.
로그인 구현
Jwt 방식을 구현하기 위해서는 Jwt 토큰을 발급해주고, 인증해주는 모듈이 필요하다. 물론 직접 공부해 Jwt 모듈을 개발할 수도 있겠지만, 개발 생산성을 위해 잘 개발된 오픈 소스를 선택했다.
Jwt 모듈을 활용해 사용자가 인증되면 토큰을 발급해주도록 로그인 기능을 개발했다.
Jwt 모듈 일부
Controller 일부
요청 인증, 인가 구현
요청에 대한 인증, 인가는 Spring Security 필터 체인에 JwtAuthenticationFilter를 추가해 구현했다.
JwtAuthenticationFilter 일부
멘토님 피드백
열심히 고민해 개발해 뿌듯했다. 하지만 멘토님께 다음의 피드백을 받았다.
마무리
어떤 방식으로 사용자 인증 기능을 구현할지 고민했다. 열심히 고민하고 내가 생각하기에 우리 팀에게 적합하다고 생각하는 방식으로 선택했다. 하지만 멘토님의 피드백을 듣고, 어떤 방식으로 로그인을 개발할지 고민했지 Jwt 방식을 깊이 있게 고민하지 않았다는 사실을 깨달았다. 정말 감사한 피드백이었다.
멘토님의 피드백을 기반으로 Jwt 방식으로 로그인을 구현하는 여러 방법을 공부하고 적합한 방식을 고민했다. 해당 내용은 다음 편에 다루겠다.
reference
'개발 경험기' 카테고리의 다른 글
[JWT 로그인 구현기] (3) Redis 도입하기 (3) | 2022.07.16 |
---|---|
[JWT 로그인 구현기] (2) JWT 로그인 개발하기 (0) | 2022.07.14 |