졸업 프로젝트 백엔드 서버 구축이 마무리 단계에 이르렀다.
현재 프로젝트는 OAuth 2.0을 사용한 소셜 로그인 + JWT를 사용하여 권한부여를 하고 있다.
회원가입 & 로그인 인증 방식을 정할 때 고려하고, 고민했던 점들을 기록으로 남기려 한다.
우선, 왜 일반적인 아이디, 패스워드 방식이 아닌 OAuth 2.0을 사용한 소셜 로그인일까?
OAuth 2.0을 이용한 소셜 로그인을 택한 이유는 여러가지가 있었다.
따라서, OAuth 2.0을 사용해서 소셜 로그인을 할 건데, 그게 다인가?
아니다.
OAuth 2.0을 사용해서 인증 처리를 하면 플랫폼에서 인가 코드가 내려오고, 주어진 인가 코드를 통해서 토큰 발급을 요청할 수 있다.
그럼 그냥 그 토큰을 사용해서 추가적인 인증 처리를 하면 될려나?
아니다!
이 생각은 정말 짧은 생각이였다.
보통 플랫폼에서 내려주는 Access Token들은 짧은 유효 기간을 가지며, 별도의 서명이나 암호화 과정이 수행되지 않은 경우도 많다.
따라서, Access Token에 담긴 사용자 식별 정보, 개인 정보들이 중간에 탈취될 수도 있다.
그럼 뭘 사용해야 하지?
보통 인증 처리를 위해 세 가지 방법을 주로 사용한다.
세션, 쿠키, JWT가 무엇인지는 이미 너무 많은 블로그에 나와있으니 생략하고, 장단점과 왜 내가 JWT를 택했는지를 알아보자!
우선, 우리가 사용하는 HTTP 프로토콜은
Stateless
하다!
Stateless
하다는 특징 때문에, 클라이언트와 서버는 서로의 이전 상태를 기억하거나, 유지하지 않는다.그럼
Stateless
하게 개발하면 만약 글을 쓰거나 로그인, 상품을 주문할 때 계속해서 새롭게 인증을 해야하나?
아니다!
그래서 나온 것이 쿠키, 세션, JWT였다.
보통 일반적인 로그인을 구현할 때 세션과 쿠키도 많이 사용한다.
하지만 여러 단점들이 존재!
우선 쿠키를 사용하는 방식은 브라우저에 데이터를 저장하여 서버에 요청시, 헤더에 쿠키를 동봉하여 보낸다.
Headers = [Set-Cookie:"userName=jinwon", "password=1234"]
그렇다면, 세션 + 쿠키 방식은 괜찮을까?
그래서 함께 사용할 수 있는 방식이 세션 + 쿠키이다.
세션은 클라이언트의 인증 정보를 쿠키가 아닌, 서버 측에 저장하고 관리한다.
Set-Cookie: SESSIONID=FD97JKHSD22KJ12NH412H51JHK2141J;
세션 + 쿠키 방식 또한 단점이 존재한다!
그에 따라 생각한 방식은 JWT!
우선, OAuth 2.0을 사용하여 소셜 로그인을 진행하면 플랫폼에서 토큰을 내려준다.
따라서 JWT로 토큰을 추가적으로 가공하여 사용하면 괜찮지 않을까?
물론, JWT를 사용하는 방식도 단점은 존재한다.
그럼에도 불구하고, 왜 JWT를 택했을까?
Stateless
가 된다.토큰 탈취 방지를 위해 어떤 전략을 사용하지?
필자의 경우, Access Token은 1시간, Refresh Token은 일주일로 현재 설정을 해놓았다.
Refresh Token을 사용함으로써, Access Token을 탈취당하더라도 짧은 토큰 유효 시간을 두어 손실을 최소화 시켰다.
또한, Refresh Token의 유효기간이 아직 만료되지 않았다면, Access Token이 만료되더라도 사용자가 요청을 보내면 재발급 가능하게 하여 사용자의 잦은 로그인을 막았다.
하지만, 항상 Trade-Off 는 존재한다!
이렇게 되면 서버는 Refresh Token을 별도의 저장소에 저장해야 한다.
나는 현재 데이터베이스가 아닌, Redis에 저장을 해두었다.
별도의 저장소가 필요없다는 JWT의 장점이 없어지지만, 그래도 OAuth 플랫폼에서 내려주는 토큰을 가공시켜 사용할 수 있다는 점, 그리고 보안을 위해 어쩔 수 없다는 점을 염두에 두어야 한다.
서비스가 결제와 같은 민감한 컨텐츠라면, 비밀번호를 한 번 더 입력하는 것이 크게 문제가 되지 않는다.
반면, 게시글에 글을 작성할 때마다 로그인을 다시 해야 한다면 사용자들은 매우 귀찮아진다.
결국 완벽한 장점만을 누릴 수는 없는 것 같다!