계밥의 작업소
JSON Web Token & Firebase Server SDK 본문
최근 Web 프로젝트 (학교 소학회에서 작품전시회 출품용)를 진행하면서 Firebase를 사용하고 있습니다. 초반엔 Facebook 로그인을 편하게 하자는 의미에서 인증 쪽만 사용하려고 했는데, Firebase Server SDK까지 손을 대게 되었네요 ㄷㄷ
Server SDK는 잘 쓰이지 않는 것 같아서, 그리고 이거때문에 개고생을 했기에 먼저 기록을 남겨보고자 합니다.
Firebase의 강점은 Database, Authentication, Hosting, Analytics 같은 Back-end 작업들을 미리 구현해놓았기에, Client 단에서 Firebase의 API만 불러오면 방금 언급한 백엔드 작업들을 손쉽게 수행할 수 있습니다.
그러나 이렇게 모든 것을 다 해놓은 것이 장점이 될 수 있지만, 단점이 될 수 있습니다. 바로 백엔드를 수정할 수 있는 범위가 많이 좁아진다는 것이죠. 한 예로, Firebase WebApp Hosting을 보면 정적인 자원들(Static Files, 생 html, css, js)만 서비스할 수 있습니다. 기존에 Template Engine 등을 이용해 응답을 보내주던 방식에 비하면 좀 무책임한(?) 호스팅이라고 볼 수 있죠.
물론 Serverless Architecture가 대두되고, Javascript Framework (AngularJS, ReactJS 등)들이 다양해지면서 Single-page Application을 제작할 수도 있으니 이런 방식의 호스팅 서비스를 하는 것이 이해갈 수도 있는 부분입니다. 그러나 개발자들이 만드는 서비스가 모두 그러하지 않듯이 기존의 Server 기반 Architecture를 무시할 수는 없죠. (실제로 저희가 제작하는 서비스도 그러합니다.)
그래서 구글은 Firebase에 대해 두 가지 유형의 Server SDK를 제공합니다. Node.js와 Java입니다. 그러나 저희는 Node.js(와 AngularJS)를 사용하기에 Java는 넘어가도록 하겠습니다 ㅎㅎ
제가 활용하려고 했던 부분은 Firebase Authetication을 통한 인증정보를 저희쪽 서버에서도 활용하고 싶었습니다. 공식 문서를 보시면 이게 가능하다고 나와있고요. (참고)
내용을 보시면 기본적으로 Firebase Authentication은 JSON Web Token(JWT)을 활용해 이루어지는 것을 알 수 있습니다. 그래서 자체 서버에서도 이러한 기능을 활용할 수가 있는 거고요.
그러나 이 망할 JWT때문에 고생 많이 했네요... Client 단에서는 그냥 AJAX 형태로 현 사용자의 JWT만 보내주면 되지만, 이를 처리하는 서버에서 문제가 생깁니다. 말이 JSON이지, 기존의 JSON 형태와 많이 다른게 JWT입니다. (그래야 보안성이 보장되겠죠?) 그래서 Node.js에서는 AJAX로 받은 요청에서는 형태가 JSON이라고는 하지만, JSON이 아닌 것을 받아 혼란스러워합니다.
서버 Error Stack Trace를 확인하시면 JWT를 받고나서 Body-parser에서 오류가 계속 나는 것을 확인하실 수 있습니다. Express-generator 등으로 만든 기본앱을 보면 body-parser가 기본적으로 내장되어 있는 것을 볼 수 있습니다. body-parser를 이용해 JSON을 처리하도록까지 미리 되어있고요. 근데 여기서 에러가 나는 겁니다. JSON을 받았으니 무작정 Parsing을 해봤는데.... 어? JSON이 아니네?! 하면서 오류를 반환합니다. (저같은 경우 400 Bad Request가 났습니다.... 이후엔 500도 뜨고요....)
해결방법은 Express 앱에서 기본으로 설정한 body-parser를 끄고, JWT를 받을 때만 body-parser를 유발시켜야하는 겁니다. (나 참.... 이게 무슨 차이라고....) 이렇게 하시면 제대로 JWT를 인식하고 복호화되는 과정을 확인하실 수 있습니다.
뭐.... 과정은 이러했습니다.... 다행이 Firebase 모듈이 JWT 모듈을 필요로하며, JWT를 확인하는 함수를 내장하고 있어 JWT 자체의 유효성 검증, 키발급, 이러한 쉩들은 신경 안써도 되었습니다. 결론 : JSON같지만 JSON같지 않은 JWT 요망한 것!
** 초안이라 두서없이 썼습니다. Gist와 사진들을 동원해 수정하도록 하겠습니다! 궁금한 점은 댓글 남겨주세요! **