[개발 일지] Hoogle Calendar(로그인_passport)

홍범선·2023년 9월 16일
0

Next.js-Hoogle_Calender

목록 보기
12/14

로그인 By passport

사용배경

로그인을 처리하는 방법은 크게 세션, jwt방식 등이 있다. 전 프로젝트에서 jwt를 사용하여 로그인을 구현한 적이 있어서 학습겸 세션방식을 채택하였다.
참고한 블로그는 다음과 같다.
[NODE] 📚 Passport 모듈 사용법 (그림으로 처리 과정 💯 이해하기)

영상은 다음과 같다.
ogin and Register Tutorial with PassportJs, MySql, and NextJs/React

세션이란?


위에 이미지를 살펴보자
클라이언트에서 로그인 요청을 보낸다.
서버에서는 로그인 체크를 한 후 사용자의 인증 정보를 서버의 세션 저장소에 저장한다.
서버는 클라이언트에게 저장된 세션 정보의 식별자인 Session ID를 발급한다.
클라이언트는 Session ID를 브라우저에 쿠키 형태로 저장된다. 하지만 실제 인증 정보는 서버에 저장된다.
클라이언트는 인증 절차를 마친 이후 요청마다 HTTP Cookie 헤더에 Session ID를 함께 서버로 전송한다.
서버에서는 Session ID에 해당하는 정보가 있는지 확인한다.

세션 보안성

세션과 jwt를 비교했을 때 보안성 측면에서 우수하다.
(브라우저 쿠키_세션)

(브라우저 쿠키_jwt)

차이가 있다.
쿠키에 저장된 session ID는 단순히 식별자이다. session ID에 별도로 인증 정보가 들어가 있지 않아 해커에 탈취된다 하더라도, 서버측에서 해당 세션을 무효 처리하면 된다.

만면에 jwt는 인증 정보를 가지고 있다. 따라서 해커에 의해 탈취된다면 인증 정보를 탈취 당할 수 있고 해당 토큰이 만료되기 전까지 속수무책으로 피해를 입는다.

세션 단점

세션은 서버에서 세션 정보를 유지하기 때문에 서버 부하가 증가할 수 있다. 또한 매 요청마다 세션ID를 서버에서 검증해야하기 때문에 네트워크 대역폭도 증가한다.
또한 서버가 여러대 있을 경우 서버 확장성 문제가 있다.

PassPort 모듈이란

Passport는 이름 그대로 서비스를 사용할 수 있게끔 해주는 여권 같은 역할을 하는 모듈이다.

여권이라는 것은 입/출국 심사시에 해당 여권 소지자가 입/출국 자격에 대해 인증하는 역할을 한다.
이를 서버에 비교해보면, 클라이언트가 서버에 요청할 자격이 있는지 인증할 때 passport 미들웨어를 사용한다.

즉 passport모듈은 로그인 절차를 확실하게 하기위해 사용하는 라이브러리인 셈이다.

Strategy 종류

Local Strategy(passport-local) : 로컬 DB에서 로그인 인증 방식 구현
Social Authentication (passport -kakao, passport-twitter 등) : 소셜 네트워크 로그인 인증 방식

본 프로젝트에선 Local Strategy방식으로 구현하였다.

로그인 과정

1. 클라이언트에서 로그인 요청을 한다.

클라이언트에서 로그인 요청을 보낸다. next.js에서 개발서버 포트는 3000번이다. next.js에서 따로 node서버를 구축해야 한다. 그래서 포트 3001인 node서버를 따로 구축하였고, login api 요청을 보낸다.

2. 서버 동작과정

서버에서 login 요청을 받고
passport.authentciate함수를 실행하는데 이때 Passport.use를 호출한다.
passport.use는 로그인 전략이라고 생각하면 된다.
DB에서 전달받은 userID, userPassword가 존재하는지 체크하고 있으면 done(null, rows[0])를
없다면 done(null, false)를 호출한다.
이제 done이 호출이 되면 다시 passport.authenticate로 돌아간다.

콜백함수 인자값은 어떻게 될까?

done의 결과 따라 콜백함수 인자값에 다음과 같이 넣어진다.

만약 user가 있다면 req.login()을 done()정보를 토대로 사용자 정보 객체와 함께 호출한다.

req.login을 실행하면 serializerUser() 호출하는데
serializeUser에서 req.session에 user.id값만 저장한다. (메모리 최적화를 위해서)
serializeUser에서 done을 실행하면 deserializeUser()를 호출한다.
deserializeUser에서 sql 조회 후 req.user 객체를 등록 후 done을 호출하여 req.login 콜백함수로 넘어간다.
req.login 콜백함수에서 세션 쿠키를 브라우저에 보낸다.

passport 로그인 이후 과정

  1. 모든 요청에 passport.session() 미들웨어가 passport.deserializeUser()를 매번 호출한다.
  2. deserializeUser에서 req.session에 저장된 아이디로 데이터베이스에서 사용자 조회
  3. 조회된 사용자 전체 정보를 req.user 객체에 저장
  4. 라우터에서 req.user를 공용적으로 사용 가능하다.

프로젝트에서 로그인 체크 로직


getUser라는 api를 서버에 호출한다.

서버에서는 getUser라는 요청이 왔으므로 미들웨어가 deseiralizeUser를 매번 호출할 것이다.그리고 나서 생긴 req.user를 클라이언트에 보낸다. req.user가 비어있으면 세션이 종료된 것이고 그렇지 않으면 세션이 유지되있는 것이다.

생겼던 오류


처음 {usernameField:'userID', passwordField:'userPassword'}없이 그냥 섰는데 해당 함수가 호출되지 않았다. 하지만 {usernameField:'userID', passwordField:'userPassword'} 추가하니 정상적으로 작동했다.

profile
알고리즘 정리 블로그입니다.

0개의 댓글