최근 카카오에 다니는 친구와 모두의파티 이름으로 토이프로젝트를 설계하고 있다.
가장 먼저 모든 페이지에 공유되는 토큰을 설계하기 위해 논의하였는데
시작부터 토론 주제가 많았다.
우리 서비스는 회원가입이 필요한가?
사용자의 접근성을 위해 카카오 로그인 API를 이용하자.
따로 정보를 더 받을 수도 있지만 우선 카카오 로그인만으로 충분해 보인다.
어떤 방식으로 인증할 것인가?
JWT 방식을 사용하기로 하자.
매번 DB를 조회하지 않아도 되니 서버 부담도 줄고 인증도 빨라서 우리 서비스에 적합하다.
카카오 로그인 API 문서에서도 지원하고 있다.
JWT는 무엇인가?
Json Web Token의 약자로 JSON으로 인증 정보를 나타내는 문자열이다.
header, payload, signature로 구성되어 있는데 재밌는 특징은 header와 payload는 암호화되어 있지 않아서
누구나 열어볼 수 있다. 그 말인 즉슨, 중요한 정보는 저 공간에 두면 안 된다.
보통 토큰의 유효기간, 위 예시에 admin 값처럼 권한 값 같은 것을 담을 수 있다.
누구나 열 수 있는데 어떻게 보안이 되나? 바꾸면 되지 않나? 라고 생각할 수 있지만
그래서 마지막 부분 signature에 암호화하여 header, payload 값을 서명한다. (secretKey는 사전에 공유되어야 한다.)
때문에 토큰을 탈취해도 조작할 수는 없다.
JWT의 단점은 무엇인가?
토큰 값이 굉장히 길기 때문에 매 요청당 길이가 길어진다.
-> 여기서 의문인 점은 HTTP2는 허프만 코딩 방식으로 Header Compression이 될텐데 매 요청당 단점이라고 할 수 있을까?
또 토큰 자체가 인증 정보이기 때문에 탈취되면 보안에 취약하다.
-> 유효기간을 짧게 가져가고 Refresh 방식을 지원하도록 하자.
-> xss, csrf 공격에도 취약할 수 있으니 프론트엔드에서 잘 대비하는 게 필요하겠다.
모두의파티 인증 서버 구조
카카오 소셜 로그인 서버 구조
카카오 소셜 로그인 서버의 처리 흐름이다.
카카오 서버에서는 access token을 받고 이 token을 가지고 JWT를 발급받는 형식이다.
따라서 JWT를 발급하고, 인증하는 서버를 개발하는 것이 필요하다.
내가 처음 프로토타입으로 제안한 인증 서버 구조
내가 처음 제안한 인증 서버 구조이다.
프론트 서버쪽에서 JWT 토큰을 발급하고 토큰을 디코딩해서 유효시간을 확인하여 인증하고 리프레쉬까지 처리한다.
여기서 많은 토론이 오갔다.
1. 프론트 서버가 JWT를 발급하는 것이 맞나? 백엔드가 처리할 것이 아닌가?
- 나의 답변은 프론트쪽 서버라고 해서 백엔드 서버와 하는 일이 크게 다르진 않다는 것이다. 사용자 브라우저들의 세션을 관리하는 역할이므로 사용자에게 가장 가까운 프론트 서버가 유효시간이며 갱신이며 관리하는 것이 더 효율적이지 않을까? 꼭 백엔드가 처리해야할 이유가 있을까? 그렇다고 프론트 서버가 그 일이 역할만 따졌을 때 완전 적합한 것은 아니지만 그렇다고 백엔드로 감춰두는 것도 좋아보이진 않았다. 나중에 프론트도 백도 아닌 별도의 인증 서버로 따로 분리시키는 것이 적합해보였다.
하지만 나도 확실하지 않다. 백엔드 친구도 확실하게 논파하진 못했다. 그래서 일단 이렇게 가고 해보면서 경험하기로 했다. 내가 확신하지 못하는 이유 중 하나는 이렇게 하게 되면 jwt 토큰의 시크릿키를 프론트 서버와 백엔드 서버가 사전에 공유해야 하기 때문이다. 보안에 더 취약한 구조 아닐까 싶어서이다. 그래서 나중엔 인증 서버를 독립적으로 둬야 한다고 생각하고 있다. 일단 해보면서 지속적으로 어떤 구조가 더 나은지 생각하기로 했다.
2. 프론트 서버와 백엔드 api 서버 간의 인증은 어떻게 할 것인가?
- 사용자의 jwt 토큰으로 인증하면 되지 않나? 서로 사전에 jwt 토큰의 시크릿키를 공유하고 인증하면 된다고 생각했다.
우리와 비슷한 고민을 한 다른 사례는 없을까?
next-auth 커뮤니티에서 비슷한 질문을 찾았는데 내가 생각했던 이상적인 구조로 구현하는 것 같다.
결론
최종적으로 우리가 생각해낸 인증 구조는 다음과 같다.
역시 나는 토이프로젝트를 할 때 가장 즐거움을 크게 느낀다.
더더 성장하고 싶다
'프로젝트 > 모두의파티' 카테고리의 다른 글
css-in-js 컴포넌트의 성능 개선과 버그 해결 (feat. useInsertionEffect in React18) (0) | 2022.10.01 |
---|