Express에서 kakao-passport 이용 질문입니다!

문의 시, 사용하시는 개발환경과 디벨로퍼스 앱ID를 알려주세요.

개발환경 - Express.js / 디벨로퍼스 앱ID : 909040


express를 이용하여 passport-kakao를 사용하여 구현중에 있습니다.

다음은 passport에 대한 코드입니다.

  1. passport/index.js
const passport = require("passport");
const Member = require("../models/member");
const kakao = require('./kakaoStrategy');


module.exports = () => {
    passport.serializeUser((user, done) => { // 로그인 시 session 저장
        done(null, user.kakaoId);
    });

    // id -> req.session.kakaoId를 의미
    passport.deserializeUser((id, done) => { // 로그인 시 세션 불러오기. req.user로 접근 가능!
        Member.findOne({ kakaoId: id })
            .then(member => done(null, member))
            .catch(err => done(err));
    });
    kakao();
}
  1. passport/kakaoStrategy.js
const passport = require("passport");
const KakaoStrategy = require('passport-kakao').Strategy;

const Member = require('../models/member')

module.exports = () => {
    passport.use(new KakaoStrategy({
        clientID: process.env.KAKAO_APIKEY, // 카카오에서 발급해주는 아이디
        callbackURL: process.env.REDIRECT_URL, // 카카오 인증 결과 라우터 주소
    }, async (accessToken, refreshToken, profile, done) => {
        try {
            // 기존에 카카오를 통해 회원 가입한 사용자가 있는지 조회
            const exUser = await Member.findOne({ kakaoId: profile.id });
            if (!exUser) { // 있으면 사용자 정보와 함께 done 함수를 호출하고 종료
                // 없으면 회원 가입 진행
                // 인증 후 콜백 라우터로 accessToken, refreshToken과 profile을 보냄.
                const newUser = await Member.create({
                    kakaoId: profile.id
                });
                return done(null, newUser);
            }
            return done(null, exUser);
        } catch (error) {
            console.error(error);
            done(error);
        }
    }));
}

카카오 로그인 → 카카오 로그인 화면 → 로그인 성공 시 로그인 콜백 [GET] → res.json의 msg를 전송.
여기까지 진행했을 때는 req.user의 값과 req.session이 저장되는 것을 확인했습니다.


이것은 req.session에 대한 것을 콘솔에 찍었을 때 나타낸 것입니다. passport의 user라는 키 값에 카카오 id가 잘 들어가는 것을 확인했습니다.

아래 코드는 해당 로그인과 로그인 콜백에 대한 코드입니다.

// 로그인 인가 요청
authRouter.get("/login", passport.authenticate("kakao"));

// 로그인 콜백 요청
authRouter.get(
    "/login/callback", passport.authenticate('kakao'), (req, res) => {
        try {
            const user = req.user;
            console.log(JSON.stringify(user));
            console.log(JSON.stringify(req.session));

            if (!user) {
                return res.status(400).json({
                    msg: "사용자가 존재하지 않음."
                })
            }
            if (user.name === null) {
                return res.json({ msg: "sign_up"})
                // res.redirect('/auth/join')
            } else {
                return res.json({ msg: "success"})
                // res.redirect('/auth/main')
            }
        } catch (error) {
            return res.status(500).json({
                message: error.message,
            });
        }
    }
);

이 이후 react 환경의 프론트엔드에서는 msg의 값이 sign_up인 경우 회원 가입 페이지로 navigate하여 회원가입을 진행하게 될 경우 다음과 같은 백엔드 코드가 실행됩니다.

authRouter.post('/join', async (req, res) => {
    try {
        console.log(JSON.stringify(req.session));
        console.log(req.user.kakaoId);

        const target = req.user.kakaoId;

        // 받은 값으로 회원 가입 완료.
        await Member.updateOne({ kakaoId: target }, {
            $set: {
                name: req.body.name,
                studentId: req.body.studentId,
                club: req.body.club,
            }
        });
        res.status(200).json({
            msg: '회원 가입 성공'
        });
    } catch (error) {
        console.error(error);
        res.status(400).json({
            message: error.message
        });
    }
});

이후 이 POST 요청이 실행됐을 때, target의 값이 undefined가 저장되어 에러가 나는 상황입니다.

여기서 각각 req.session과 req.user.kakaoId를 콘솔에 찍어봤을 때 다음과 같이 나왔습니다.

req.user가 왜 undefined인지 문제를 해결해주시면 감사하겠습니다…

아쉽지만, undefined는 개발하신 시스템에서 매핑이 잘못된것으로 카카오에서 해결해드릴 수 없습니다.

각단계별 변수값을 로깅 해보시면 좋을 것 같고
관련된 전체 full 로그 기재하시면 추가로 개발하신 로직에 어떤 문제점 있을지 검토 해보도록 하겠습니다.