배포를 목표로 새로운 프로젝트를 진행하기 시작했습니다. 실제 배포를 목표로 하는 프로젝트이므로 로그인 기능을 보다 안정적으로 구현하고자 했습니다.
그렇게 '인증 기능이야 거의 모든 서비스가 다루고 있는 기술이므로 정형화되어 있을 것이고, 잘 정리된 글을 따라하면 되겠다.' 라는 생각으로 열심히 구글링을 했지만, 막상 구현방법이 너무나 다양했습니다.
이 글에서는 로그인 구현의 정석을 찾기위해 고민한 내용을 정리해보겠습니다.
※ 개인적인 의견이 많이 포함돼 있습니다! 잘못된 내용, 다른 의견이 있다면 댓글로 남겨주세요😊
글 서두에서 말했듯이 로그인 기능 구현 방식이 너무나 다양했습니다. 특히 보안 문제까지 들어가면 아직 로그인을 구현하는 방법이 완성되지 않은건가? 하는 생각까지 들었습니다.
가장 기본이 되는 로그인 구현이 이렇게나 복잡하고 정답이 없다는 것이 답답해서 하루종일 구글링을 했고, 구글링 끝에 로그인 구현에 대한 정답(?)을 찾기 어려운 이유를 다음과 결론내렸습니다.
(1) 요구사항에 따라 구현이 달라진다.
생각해보면 애초에 사이트마다 로그인을 처리하는 방법이 조금씩 다릅니다.
ex)
이 외에도 서비스 내용에 따라 많은 내용이 달라질 것이고, 따라서 로그인 구현에 대한 정답이 없는 것도 어떻게 보면 당연한 듯 합니다.
(2) 보안문제
로그인을 어떻게 구현했는지 자세히 공개하는 것은 보안문제로 이어질 수 있습니다. 이번에 공부를 하며 XSS나 CSRF 같은 공격 기법을 접하면서 '공격을 완벽하게 차단하는 것이 생각보다 훨씬 어렵다' 라는 것을 느꼈습니다.
결국 어떻게 구현하더라도 조금의 허점은 존재할 것이고, 그러한 허점을 드러내지 않기 위해 자세한 구현을 공개하지 않을 것 같습니다.
결국 크게 3가지 사항, 'UX, 보안레벨 그리고 서비스 규모'를 먼저 결정해야 구현 방식을 결정할 수 있다고 결론내렸습니다.
(1) UX
앞서 말한 것처럼 서비스마다 인증에 대한 UX가 다릅니다. 따라서 자신의 서비스에서는 어떤 UX를 제공할 것인지를 먼저 생각해봐야됩니다.
이에 따라 구현 방향도 달라질 것입니다.
(2) 보안레벨
생각보다 많은 글이 JWT 기반 인증을 구현하면서, access token이나 refresh token을 냅다 로컬 저장소에 저장해두었습니다. 결론적으로 말하면 이는 보안에 매우 취약합니다.
XSS나 CSRF 공격에 취약합니다.
보안레벨을 3단계로 나눠보고 그에 따라 달라지는 구현방법을 간단하게 정리해보겠습니다.
(임의로 설정한 보안레벨입니다!)
① 연습용 프로젝트
공부용, 연습용 프로젝트로 사용되어 보안이 중요하지 않는 경우입니다. 이 경우에는 access token을 로컬 저장소에 저장하도록 구현해도 문제가 되지는 않겠죠.
② 일반 프로젝트
보안을 신경써야되는 서비스의 경우입니다.
최소한 XSS나 CSRF와 같이 잘 알려진 공격에 대한 보안 설정은 적용되어야 합니다.
JWT 기반 인증을 기준으로 했을 때, XSS나 CSRF 방어 방법으로 다음과 같은 방법들을 접할 수 있었습니다.
③ 보안이 중요한 프로젝트
금융 서비스처럼 보안이 매우 중요한 경우입니다. 이러한 경우에는 각 서비스에 최적화된 구현 방식을 직접 고안해야 합니다.
간단한 예로는 로그인이 유지 기능을 삭제하는 것도 한 방법이 될 수 있겠네요.
(3) 사용자 규모 (JWT vs Session)
사용자 규모도 로그인 구현 방식을 결정하기 위해 고려해야될 요인이었습니다.
예를 들어 세션 방식으로 로그인을 구현한 경우, 사용자가 많이 몰릴 수록 서버의 부담이 커지죠. 이에 비해 JWT는 서버의 부담이 없으므로, 확장성이 좋다고 알려져있습니다.
그럼 규모가 크면 무조건 JWT를 쓰면 될까요? 그것도 아니었습니다.
여러 글을 봤지만, 사용자 규모만으로 JWT와 세션 중 어떤 방식을 이용할지 결정하는 것은 무리가 있었습니다.
이유는 다음과 같습니다.
결론