계획의 재검토
지난번 작성한 Passport.js 글에서도 잠깐 언급했지만, 그 다음 강의는 DATABASE2 - lowdb 강의였다. 하지만, 강의 영상이 제작된 이후 lowdb가 2.0 버전으로 업데이트 되었는데, 문법이 많이 바뀌어 학습에 어려움이 있을 것 같았다. 이와 더불어 전역 후에는 알고리즘 공부를 하려고 계획하고 있었기 때문에, 공부 계획을 재검토하게 되었다. 웹 프로그래밍 공부 중단 및 알고리즘 공부 시작, lowdb가 아닌 다른 데이터베이스를 사용한 웹 프로그래밍 공부 지속 등의 방안이 있었다. 우선, 학습하고 있던 WEBn 시리즈 완강이 얼마 남지 않아 여기서 중단하기엔 너무 아쉽다는 판단이 섰다. 이후 웹 공부를 지속하기 위해 정보를 조사하던 중, 다행히 npm으로 패키지의 특정 버전을 다운로드 할 수 있다는 사실을 알게 되었다. 덕분에 다른 데이터베이스를 사용하지 않고, 강의에서 사용하는 lowdb 1.0을 설치 해 학습하고, 웹 공부를 더 이어갈 수 있었다.
DATABASE2 - lowdb
이고잉님의 말씀대로, lowdb는 매우 가벼운 데이터베이스여서 학습에 오랜 시간이 걸리지 않았다. 이전에 MySQL을 학습해서인지 기본적인 CRUD는 문법만 조금 달랐지 크게 어렵지 않았다. MySQL 학습 때와 마찬가지로, 웹에서의 조작을 통해 데이터베이스를 제어할 수 있다는 부분이 재미있었다.
WEB5 - Passport - REWORK
lowdb를 학습 한 이후, WEB6로 넘어가기 전, WEB5 - Passport를 한 번 더 학습하게 되었다. 사실 처음부터 의도한 것은 아니었고, 그럴 수 밖에 없는 상황이 생겼기 때문이다. WEB6는 WEB5를 기반으로 하는 수업이라, Github의 WEB5 저장소를 그대로 복제해 WEB6 저장소를 생성하고 로컬에 다운로드했다. Passport가 워낙 어려운 내용이었기에, 새로운 진도를 나가기 전에 프로그램 작동 원리를 다시 한 번 정리하고 넘어가고자 코드를 건들지 않고 그대로 실행해 보았다. 하지만 여기서 문제가 발견되었다.
구름IDE 환경에서는 정상적으로 동작했던 로그인 기능이 동작하지 않았던 것이다. 처음에는 너무 당황스러웠다. 몇 번에 걸쳐 프로그램을 다시 실행시켜보고, 잘못된 부분이 없는지 코드를 둘러보았지만, 코드에는 잘못된 부분이 없었다. 동일한 프로그램이 실행 환경만 바뀌었는데 작동하지 않았기 때문에 패키지 설치를 잘못 한 것이라고 추측해 npm으로 패키지 재설치를 진행했다. 하지만 패키지 재설치로도 문제는 해결되지 않았다. 이에 내 코드에 문제가 있다고 생각해 강사인 이고잉님이 올려 둔 파일을 다운로드해 실행했지만, 최초 1회만 로그인에 성공하고 이후로는 계속 실패했다. 나의 멘탈에는 금이 가기 시작했다.
WEB5가 제대로 동작하지 않는다면 그 다음 강의인 WEB6도 진행할 수 없어 문제를 해결하기 위해 분석을 진행했다. 코드 검토 결과, 상당히 이상한 점이 발견되었다. 프로그램은 로그인 성공 시, 결과적으로 '세션 저장소에 사용자 정보 저장, 홈 화면으로 리다이렉션'의 두 가지 동작을 수행해야 하는데, 홈으로의 리다이렉션은 정상적으로 실행되나 세션 저장소에는 사용자 정보가 저장되지 않았던 것이다. 하지만 이 원인은 알 수 없었다. 구글링을 통해 정보를 조금 찾아보며 문제를 해결하려고 했으나, 이 참에 Passport를 다시 한 번 학습하는 게 좋겠다는 생각이 들었다. Passport 글에서도 고백했지만, 어려운 내용임에도 군대에서 마지막에 공부에 소홀했던 탓에 이해도가 완벽하지 않다고 생각했기 때문이다. 처음부터 다시 학습한다면, 로그인 서비스를 구현하는 과정에서 문제점을 발견할 수 있을 것이라고 생각했다.
기존의 WEB5-Passport 저장소에 Rework라는 이름의 새로운 분기(Branch)를 생성했고, 처음부터 Passport를 다시 학습했다. 학습을 진행하며 Passport local 인증 과정을 차근차근 정리하기도 했는데, 덕분에 전체적인 인증 과정을 이해하는 데에 큰 도움이 되었다.
passport-local 인증 과정
1. /auth/login에서 사용자 정보 입력, 입력된 정보는 form 형식으로 /auth/login_process로 전송
2. /auth/login_process의 passport.authenticate 메소드 실행. local 방식이라고 명시되어 있으므로, local strategy 메소드 실행
3. local strategy 메소드 (passport.use(new LocalStrategy))에 form 데이터 전송. callback 함수에서 전송된 데이터와 authData 비교
4. 로그인 성공 시, done의 두 번째 인자에 authData 주입 (로그인 실패 시, done의 두 번째 인자에 false 주입)
5. 주입된 사용자 정보는 serializeUser의 callback 함수의 첫 번째 인자(user)로 주입
6. serializeUser의 callback 함수에서 사용자 식별자(user.email)를 추출해 done의 두 번째 인자로 주입. 주입된 식별자는 세션 데이터의 passport의 user 값으로 저장
7. 페이지에 방문할 때, deserializeUser의 callback 함수의 첫 번째 인자(id)에 세션 데이터로부터 식별자 주입
8. deserializeUser의 callback 함수에서, 식별자를 이용해 데이터베이스 조회, 사용자 유무 판별. 세션으로부터 받은 데이터(id)와, DB 데이터(authData)의 email이 일치 할 경우, 사용자 존재
9. 사용자가 존재 할 경우, deserializeUser의 callback 함수에서 done의 인자로 사용자 정보(authData) 주입. 이 사용자 정보는 request.user 객체에 전달
코드는 조금씩 길어졌고, 마침내 문제가 발생했던 로그인 정보를 세션 데이터에 저장하는 부분에 도착했다. 강의를 주의 깊게 들으며 잘 따라왔음에도 불구하고, 기존과 같은 문제가 발생했다. 강의 영상에서는 프로그램이 문제가 없이 작동했지만, 내 프로그램은 작동하지 않았다. 문제를 해결하기 위해 구글링을 통해 정보 조사를 진행했다, 그러던 중 생활코딩 커뮤니티에 들어갔는데, 그곳에서 나와 같은 문제를 겪고 있는 많은 사람들을 발견하게 되었다. 내가 분석한 것과 마찬가지로, 문제는 사용자 정보가 세션 저장소에 저장되지 않는다는 점이었다. 다른 유저들 역시 정확한 이유는 파악하지 못했지만, 세션 데이터가 저장되기 전에 페이지가 리다이렉션 되는 경우가 있다는 대략적인 이유는 알아낼 수 있었다. 리다이렉션 되는 것을 방지하기 위해, 로그인이 완료되고 리다이렉션 되기 전에 명시적으로 세션을 저장하는 코드를 작성했다.
또한, 프로세스 관리자인 PM2의 서버 자동 재시작 옵션 역시 문제가 될 수 있다는 것을 알게 되었다. --watch 옵션을 줄 경우 PM2는 파일의 변경을 감지해 서버를 자동으로 재시작하는데, 이 때문에 세션 데이터가 제대로 저장되기 전에 서버가 닫혀버리는 문제가 발생했다. 이를 해결하고자 PM2에 세션 파일의 변경을 무시하라는 --watch-ignore 옵션을 주었고, 세션 데이터의 변경으로 서버가 재시작 되는 것을 방지했다.
리다이렉션 전의 명시적인 세션 데이터 저장, 세션 데이터 변경 전 서버 재시작의 방지의 두 가지 방법을 활용해 정상적인 로그인 기능을 구현할 수 있었다. 그 뒷 부분에서는 큰 문제는 없었지만, flash message를 구현 할 때에도 마찬가지로 flash 데이터가 세션에 저장되지 않는 현상이 있었다. 다만, flash는 인증 과정에 크게 중요한 부분이 아니라 부차적인 기능에 불과했기 때문에, 비활성화하고 추후에 해결하기로 했다.
지금까지 웹 프로그래밍을 공부하면서, 이번 Passport 인증 과정에서 발생한 문제를 해결하는 것이 가장 어려웠던 것 같다. 하지만, 인증 과정을 처음부터 다시 구현하며 차근차근 정리해 내용을 더 완벽하게 이해할 수 있었고, 덕분에 WEB6, WEB7를 학습하는 데에 큰 도움이 될 것 같다. 또한, 개발을 하는 과정에서 문제가 발생할 경우, 그 원인을 분석하고 문제를 해결하기 위해 어떤 식으로 접근해야 하는지 배울 수 있었다. 이번 경험을 통해 한 단계 더 성장한 것 같아 기분이 좋았고, 앞으로 남은 WEBn 강의들도 잘 학습하고 싶다.
강의명 : Opentutorials - DATABASE2 - lowdb
학습 기간 : 2021.07.22 ~ 2021.07.23
강의명 : Opentutorials - WEB5 - Passport _ REWORK
학습 기간 : 2021.07.25 ~ 2021.07.26
'Dev' 카테고리의 다른 글
WEB7 - Login with Google / Facebook on Passport (0) | 2021.08.06 |
---|---|
WEB6 - Multi User Auth / WEB2 - OAuth 2.0 (0) | 2021.07.31 |
WEB5 - Passport.js (0) | 2021.07.21 |
WEB3 - Node.js - Cookie & Auth / WEB4 - Express - Session & Auth (0) | 2021.06.03 |
WEB3 - Express (0) | 2021.04.23 |