passport
- serializeUser: 로그인 시에만 실행, 객체에 어떤 데이터를 저장할지 정함
- deserializeUser: 매 요청 시 실행, 세션에 저장한 아이디를 통해 사용자 정보 객체를 불러옴
- sU의 두번째 인수로 넣었던 데이터가 dU의 매개변수가 됨. sU에서 세션에 저장했던 아이디를 받아 데이터베이스에서 사용자 정보를 조회함. 조한 정보를 req.user에 저장함
- 라우터를 통해 로그인 요청이 들어옴
- 라우터에서 passport.authenticate 메서드 호출
- 로그인 전략 수행
- 로그인 성공 시 사용자 정보 객체와 함께 req.login 호출
- req.login 메서드가 passport.serializeUser 호출
- req.session에 사용자 아이디만 저장
- 로그인 완료
- 로그인 이후, 요청이 들어옴
- 라이터에 요청이 도달하기 전에 passport.session 미들웨어가 passport.deserializeUser 메서드 호출
- req.session에 저장된 아이디로 데이터베이스에서 사용자 조회
- 조회된 사용자 정보를 req.user에 저장
- 라우터에서 req.user 객체 사용 가능
bcrypt: const hash = await bcrypt.hash(password, 12);
- 두번째 인수는 pbkdf2의 반복 횟수와 비슷한 기능을 함, 12 이상을 추천하며 31까지 사용 가능
- 라우터 미들웨어 내부의 미들웨어에는 끝에 (req, res, next)를 인수로 제공해서 호출
- 로그인: 전략이 성공하거나 실패하면 authenticate 메서드의 콜백함수가 실행됨. 콜백 함수의 첫번째 매개변수(authErr) 값이 있다면 실패, 두번째 매개변수 값이 있다면 성공, req.login 메서드 호출. Passport는 req 객체에 login과 logout 메서드를 추가. req.login은 passport.serializeUser 호출해서 user 객체가 넘어감
- 로그아웃: req.logout 메서드는 req.user 객체를 제거. req.session.destroy는 req.session객체의 내용을 제
passport-local
LocalStrategy 생성자의 첫번째 인수: 전략에 관한 설정. usernameField와 passwordField에는 일치하는 로그인 라우터의 req.body 속성명을 적음
두번째 인수: 실제 전략을 수행하는 async 함수. 첫번째 인수의 email과 password는 각각 async 함수의 매개변수가 됨. 세번째 매개변수인 done 함수는 passport.authenticate의 콜백 함수
- 사용자 디비에서 일치하는 이메일이 찾음
- 있다면 bcrypt의 compare 함수로 비밀번호를 비교, 일치하면 done에 두번째 인수인 사용자 정보를 넣어 호출
- 첫번째 인수를 사용하는 경우: 서버 쪽에서 에러가 발생
- 세번째 인수를 사용하는 경우: 로그인 처리 과정에서 비밀번호가 일치하지 않거나 존재하지 않는 회원일 때 등 사용자 정의 에러가 발생
done(null, exUser) passport.authenticate('local', (authError, user, info) done(null, false, { message : ' ~ ' }) passport.authenticate('local', (authError, user, info) done(error) passport.authenticate('local', (authError, user, info)
passport-kakao
- 카카오 로그인 설정: clientID, callbackURL
- 기존에 카카오를 통해 회원가입한 사용자가 있는지 조회, 있다면 사용자 정보와 함께 done을 호출하고 전략을 종료
- 없다면 회원가입 진행. 카카오에서는 이증 후 callbackURL에 적힌 주소로 accessToken, refreshToken과 profile을 보냄. 사용자 생성 후 done 호출
- passport.authenticate 메서드에 콜백 함수를 제공하지 않음. 로그인 성공 시 내부적으로 req.login을 호출함. 실패했을 때 어디로 이동할지를 failureRedirect 속성에 적고, 성공 시에도 어디로 이동할지를 다음 미들웨어에 적음
- deserializeUser: 라우터가 실행되기 전에 먼저 실행됨. 따라서 모든 요청이 들어올 때마다 매번 사용자 정보를 조회함. 서비스의 규모가 커질수록 더 많은 요청이 들어오고 디비에도 부담이 되므로 사용자 정보가 빈번하게 바뀌는 것이 아니면 캐싱을 해두는 것이 좋음. 다만 캐싱이 유지되는 동안 팔로워와 팔로잉 정보가 갱신되지 않는 단점이 있으므로 캐싱 시간은 서비스 정책에 따라 조절해야 함. 실제 서비스에서는 메모리에 캐싱하기보다는 레디스 같은 디비에 캐싱함.
'괴발개발 > node.js' 카테고리의 다른 글
[node.js 교과서] ch12. 웹 소켓으로 실시간 데이터 전송하기 (0) | 2023.02.07 |
---|---|
[node.js 교과서] ch10. 웹 API 서버 만들기 (0) | 2023.02.07 |
[Node.js 교과서] ch8. 몽고디비 (0) | 2023.02.02 |
[Node.js 교과서] ch7. MySQL (0) | 2023.02.02 |
[Node.js 교과서] ch6. 익스프레스 웹 서버 만들기 (0) | 2023.02.02 |