인프런 커뮤니티 질문&답변

hyeokim님의 프로필 이미지
hyeokim

작성한 질문수

[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지

카카오로 로그인하기

카카오 로그인 내부 동작 순서 관련 질문입니다.

작성

·

300

0

// auth.js
router.get('/kakao', passport.authenticate('kakao'));

router.get('/kakao/callback', passport.authenticate('kakao', {
  failureRedirect: '/',
}), (req, res) => {
  res.redirect('/');
});

// kakaoStrategy.js

module.exports = () => {
  passport.use(new KakaoStrategy({
    clientID: process.env.KAKAO_ID,
    callbackURL: '/auth/kakao/callback',
  }, async (accessToken, refreshToken, profile, done) => {
    console.log('kakao profile', profile);
    try {
      const exUser = await User.findOne({
        where: { snsId: profile.id, provider: 'kakao' },
      });
      if (exUser) {
        done(null, exUser);
      } else {
        const newUser = await User.create({
          email: profile._json && profile._json.kakao_account_email,
          nick: profile.displayName,
          snsId: profile.id,
          provider: 'kakao',
        });
        done(null, newUser);
      }
    } catch (error) {
      console.error(error);
      done(error);
    }
  }));
};

위의 코드는 질문과 연관된 코드로 질문의 이해를 돕기위해 첨부하였습니다

다음은 카카오톡 로그인 버튼을 눌렀을 때, 정상적으로 로그인 인증이 진행되는 과정에서 콘솔에 찍히는 로그입니다. 각 로그의 구분을 위해서 1~5번까지 번호를 순서대로 매겼습니다.

// (1)
GET /auth/kakao 302 4.599 ms - 0
// (2)
kakao profile {
  provider: 'kakao',
  id: 1807557207,
  // 생략
}
// (3)
Executing (default): SELECT `id`, `email`, `nick`, `password`, `provider`, `snsId`, `createdAt`, `updatedAt`, `deleteddAt` FROM `users` AS `User` WHERE (`User`.`deletedAt` IS NULL AND (`User`.`snsId` = 1807557207 AND `User`.`provider`  
= 'kakao')) LIMIT 1;
// (4)
GET /auth/kakao/callback?code=AqnOGyk-OUAvtmCijPwAZZL9Xv6LaN_C1p0f5hSQDpgN2pq9hLJIx_rAAN3-bJJ9DQQgUgopdSkAAAF6qRsigA 3
302 288.890 ms - 46
// (5)
Executing (default): SELECT `id`, `email`, `nick`, `password`, `provider`, `snsId`, `createdAt`, `updatedAt`, `deleteddAt` FROM `users` AS `User` WHERE (`User`.`deletedAt` IS NULL AND `User`.`id` = 2);

강의를 보며 카카오 로그인 과정을 이해하기로는
1. `GET /auth/kakao` 요청
2. 카카오 로그인 페이지로 리다이렉트, 로그인 및 인증 진행
3. 카카오 로그인 정보와 함께 `GET /auth/kakao/callback`으로 콜백 요청
4. 콜백 요청에 대한 라우팅이 되어있으므로, 두번째로 카카오 로그인 전략 수행
5. passport.use의 콜백 함수 실행, 로그인 검증 과정 진행
6. 로그인 성공 / 실패에 따른 리다이렉트

와 같이 이해하였습니다.

그러나, 콘솔 로그 결과를 살펴봤을 때는 조금 다른 흐름으로 동작하는 것 같은 느낌을 받았습니다. 콘솔 로그를 바탕으로 로그인 과정을 생각해봤을 때는

1. `GET /auth/kakao` 요청
2. 카카오 로그인 페이지로 리다이렉트, 로그인 및 인증 진행
3. passport.use의 콜백 함수 실행.
  -> 카카오 프로필 콘솔 출력의 결과로 (2)와 같은 로그가 찍힘
  -> profile.id 를 통해 유저가 존재하는지 조회 (findOne)
  -> 로그인 진행
  -> serializeUser 호출
4. `GET /auth/kakao/callback`으로 콜백 요청
  -> (4) 의 결과를 통해 위 과정을 거친 뒤에 콜백 요청이 일어남을 알 수 있음
5. 이미 로그인이 되어있으므로 deserializeUser 호출
  -> (5)에서 유저 정보를 조회할 때 세션에 등록된 id로 유저를 조회함
6. 로그인 성공 / 실패에 따른 리다이렉트

와 같은 흐름이어야 콘솔 로그 결과와 매칭이 되지 않을까하는 생각이 들었습니다.

결론적으로, 카카오 로그인 과정은 설명을 잘해주셔서 이해가 갔지만, 콘솔 로그의 결과에는 조금 의아한 부분이 있어 어떤 흐름으로 이해하고 넘어가면 될지 궁금하여 질문을 드렸습니다. 긴 글 읽어주셔서 감사합니다. 

 강의 영상 너무 잘 보고 있습니다. 감사합니다!!

답변 3

1

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

GET /auth/kakao 카카오같은 모건 로그는 해당 요청 시작이 아니라 해당 요청의 응답이 마무리 되었을 때 찍힙니다.

1. `GET /auth/kakao` 요청 -> 요청이 아니라 응답

이 사실을 토대로 다시 한 번 흐름을 파악해보세요.

0

hyeokim님의 프로필 이미지
hyeokim
질문자

  1. GET /auth/kakao 요청
  2. 카카오 로그인 페이지로 리다이렉트, 로그인 및 인증 진행
  3. 카카오 로그인 정보와 함께 GET /auth/kakao/callback으로 콜백 요청
  4. GET /auth/kakao 응답
    → (1) 과 같이 응답 로그 출력
  5. GET /auth/kakao/callback 을 통해 두번째 로그인 전략 수행
    → passport.use의 콜백 함수 실행, 로그인 검증 과정 진행
    → 이 과정에서 프로필 결과를 출력했으므로 (2)와 같은 로그가 찍힌다.
    [profile.id]  를 통해 유저 조회 (3)
    → 로그인 검증 과정 진행
    → 로그인 성공 혹은 실패
  6. GET /auth/kakao/callback 응답
    → (4) 와 같이 응답 로그 출력
  7. 로그인 성공 / 실패에 따른 리다이렉트
  8. 리다이렉트 요청 시 passport.deserializeUser 호출
    → (5) 와 같이 세션 id 를 이용하여 유저 정보 조회
  9. GET / 응답
    → (6) 과 같이 응답 로그 출력

0

hyeokim님의 프로필 이미지
hyeokim
질문자

아하 ㅜㅜ 완전히 접근부터 잘못되었군요..
말씀해주신 부분을 토대로 흐름을 살펴보니 이해가 되었습니다! 감사드립니다!!

hyeokim님의 프로필 이미지
hyeokim

작성한 질문수

질문하기