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

김영돈님의 프로필 이미지
김영돈

작성한 질문수

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

deserializeUser 이해하기

logout시 req.user는 undefined 인 이유.이렇다면 로그인을 안하는 것 아닐까요?

작성

·

906

0

로그인을 한 후 로그아웃을 해보았습니다. 로그인을 하면 /profile 페이지로 가게되고  /auth/logout을 하면  / 로 돌아옵니다.
/auth/loginn을 하게 되면  로그가 아래와 같이 잘 찍히고 페이지 이동도 잘 됩니다. 

Executing (default): SELECT `id`, `email`, `nick`, `password`, `provider`, `snsId`, `createdAt`, `updatedAt`, `deletedAt`, `followingId`, `followerId` FROM `users` AS `User` WHERE (`User`.`deletedAt` IS NULL AND `User`.`email` = 'ydkim@gmail.com');

POST /auth/login 302 292.273 ms - 60

GET /profile 304 0.878 ms - -

GET /main.css 304 3.621 ms - -

/auth/logout을 할 때 강의에서 말씀하신 대로

router.get("/logout", (req, res) => {
console.log(req.isAuthenticated());
console.log(req.user);
console.log(req.session);

req.logout();
req.session.destroy();
res.redirect("/");
});

이렇게 해보았는데 로그는 아래와 같이 나옵니다. 유저가 로그인 되었다는 session이나 쿠키를 어떻게 확인하나요? 그리고 req.user은 어떻게 확인하나요?

POST /auth/login 302 312.140 ms - 60

GET /profile 304 17.371 ms - -

GET /main.css 304 16.912 ms - -

false

undefined

Session {

  cookie: {

    path: '/',

    _expires: null,

    originalMaxAge: null,

    httpOnly: true,

    secure: true

  }

}

GET /auth/logout 302 4.894 ms - 46

GET / 304 9.218 ms - -

GET /main.css 304 2.477 ms - -

답변 16

1

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

saveUninitialized는 true나 false나 크게 상관은 없습니다.

1

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

session에서 cookie secure true로 되어있는데 false로 바꾸세요. https일때만 true로 하시면 됩니다.

1

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

set cookie가 없는게 문제네요. express-session만 보면 될 것 같습니다. app.use(session쪽 코드 보여주세요.

1

김영돈님의 프로필 이미지
김영돈
질문자

  1. 로그아웃 전에는 deserializeUser가 호출 안되는 상황이신거죠?
    passport>index.js 에서 console.log(user.id)를 찍어보면 1 이라는 id가 잘 찍혀서요. 일단 serializeUser은 잘 되는 것 같습니다. 그 아래 deserializer도 코드에 문제가 없어 보니는데 잘 작동해야 하는 것 같습니다.
    module.exports = () => {
    passport.serializeUser((user, done) => {
    done(null, user.id);
    console.log(user.id);
    });

    passport.deserializeUser((id, done) => {
    User.findOne({ where: { id } })
    .then((user) => done(null, user))
    .catch((err) => done(err));
    });

    local();
    // kakao();
    };
  2. 프론트 브라우저 콘솔에서 애플리케이션 탭 쿠키에는 connect.sid 들어가나요? 안 들어간다면 /auth/login이 잘못 작성된 것입니다.
    말씀대로 /auth/login이 잘 못 될 수도 이겠는데 아래와 같이 이게 autherror도 없고 user을 잘 받아와서 return req.login(user, (loginError) => {
    if (loginError) {
    console.error(loginError);
    return next(loginError);
    }
    return res.redirect("/");
  3. 위와 같은 코드가 잘 작동하고 이 이후에  / 로 리다이렉트 되는데  이 때 브라우저에 쿠키에 세션을 넣어서 보내는 것으로 이해하고 있습니다.  /로 리다이렉트는 잘 되고 다만 set-cookie 항목이 아래 처럼 없는 것 같습니다. 


1

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

로그아웃 전에는 deserializeUser가 호출 안되는 상황이신거죠? 프론트 브라우저 콘솔에서 애플리케이션 탭 쿠키에는 connect.sid 들어가나요? 안 들어간다면 /auth/login이 잘못 작성된 것입니다. 브라우저에 로그인 시 쿠키가 가야지만 그 다음 요청부터 쿠키를 활용하여 deserializeUser에서 req.user를 만들어냅니다.

1

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

deserializeUser는 serializerUser 밑에 작성하셨나요?

1

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

다른 강좌랑 착각했네요. withCredentials는 같은 주소이므로 안 하셔도 됩니다. deserializeUser랑 serializeUser는 passport 폴더 내에 작성하셨죠? 여기 안에 console.log를 찍어보세요. 특히 로그인 후에 serializeUser가 호출되어야 하고, logout 전에 deserializeUser가 호출되어야 합니다.

또한 app.js에서 passport.initialize와 passport.session 미들웨어도 연결하셨는지 확인해보세요.

1

김영돈님의 프로필 이미지
김영돈
질문자

연관수업

deserializeUser 이해하기

현재 진도는 여기인데요. 어디까지 더 들으면 되나요?  api 서버에서 cors가 나오는 것 같기는 하던데. 
그리고 궁금한건데 수업중에 axios에 withCredentials: true 이것을 안하셔도 카카오로 로그인하기 강좌에서 보면 로그인이 잘 가고 set cookie도 브라우저 네트워크 탭에서 잘 되던데...전  axios에 withCredentials: true을 왜 , 어떻게 하는 것인지 미궁입니다.

몇일째 여기만 하고 있는데 쉽지가 않습니다. ㅋ

1

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

axios에 withCredentials: true 넣으셔야 하고, 지금 문제는 cors도 적용해야 합니다. 이후 강좌를 보시면 해결될 것 같네요.

1

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

로그아웃 때 req.user, req.isAuthenticated()이 안 뜬다면 로그인이 안 된 것입니다. 프론트에서 withCredentials: true 넣으셨나요? 쿠키가 서버로 전송되어야 로그인되었는지 아닌지를 서버가 알 수 있습니다.

0

김영돈님의 프로필 이미지
김영돈
질문자

아래 설정을 바꾸니 set-cookie가 되네요.

secure: false,

감사합니다. 역시 제가 설정을 이상하게 한 탓이네요.

이렇게 까지 응답을 해주셔서 감사합니다.

그래도 오늘 원인을 알게되어서 덜 찜찜할 것 같습니다. 감사합니다!!!!!!!!!!!!!

0

김영돈님의 프로필 이미지
김영돈
질문자

감사합니다.

아무래도 

saveUninitialized: true,

이렇게 설정한 것이 틀린거 아닌거 싶네요

0

김영돈님의 프로필 이미지
김영돈
질문자

  1. 죄송합니다. 너무 귀찮게 해드리는 것 같아요. 
    // 환경 설정하기
    const dotenv = require("dotenv");
    dotenv.config();
    const path = require("path");

    const express = require("express");

    const passport = require("passport");
    const passportConfig = require("./passport");

    const { sequelize } = require("./models");
    const nunjucks = require("nunjucks");

    const { isNotLoggedIn } = require("./routes/middlewares");

    const app = express();
    app.set("port", process.env.PORT || 3004);
    passportConfig();
    // logger 설치
    const morgan = require("morgan");
    app.use(morgan("dev"));

    // cookie & session
    const cookieParser = require("cookie-parser");
    const session = require("express-session");

    // html template engine 설치
    app.set("view engine", "html");
    nunjucks.configure("views", {
    express: app,
    watch: true,
    });
    sequelize
    .sync({ force: false })
    .then(() => {
    console.log("DB가 성공적으로 연결되었습니다. 좋았어!!!");
    })
    .catch((err) => {
    console.error(err);
    });

    // parser 설치
    app.use(express.json());
    app.use(express.urlencoded({ extended: true }));

    // cookie & session 설정
    app.use(cookieParser(process.env.SECRET_CODE));
    app.use(
    session({
    secret: process.env.SECRET_CODE,
    resave: false,
    saveUninitialized: true,
    cookie: {
    secure: true,
    httpOnly: true,
    },
    })
    );

    app.use(passport.initialize());
    app.use(passport.session());

    // routing 하기
    app.use(express.static(path.join(__dirname, "public")));

    const pageRouter = require("./routes/page");
    const authRouter = require("./routes/auth");

    app.use("/", pageRouter);

    app.use("/auth", authRouter);

    // 에러 처리하기
    app.use((res, req, next) => {
    const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
    error.status = 404;
    next(error);
    });

    app.use((err, req, res, next) => {
    res.locals.message = res.message;
    res.locals.error = process.env.NODE_ENV !== "production" ? err : {};
    res.status(err.status || 500);
    res.render("error");
    });

    // 서버 연결
    app.listen(app.get("port"), () => {
    console.log(`${app.get("port")}번 port에서 test서버가 실행중입니다.`);
    });


  2. .dotenv는 이렇습니다.
    PORT = 3003
    SECRET_CODE = kydcookie
    KAKAO_ID = 25845e0475ef710d537909191eda47d0

0

김영돈님의 프로필 이미지
김영돈
질문자

  • passport>index.js 에 아래와 같이 작성되어 있습니다.
  • const passport = require("passport");
    const local = require("./localStrategy");
    // const kakao = require("./kakaoStrategy");
    const User = require("../models/user");

    module.exports = () => {
    passport.serializeUser((user, done) => {
    done(null, user.id);
    console.log(user.id);
    });

    passport.deserializeUser((id, done) => {
    User.findOne({ where: { id } })
    .then((user) => done(null, user))
    .catch((err) => done(err));
    });

    local();
    // kakao();
    };

0

김영돈님의 프로필 이미지
김영돈
질문자

  • passport>index.js 에 작성했고
  • 로그인 한 후
  • module.exports = () => {
    passport.serializeUser((user, done) => {
    done(null, user.id);
    console.log(user.id);
    });
  • 위와 같이 콘솔로 찍어보니 1 이라는 user.id가 잘 찍힙니다. 
  • app.js에는 아래와 같이 모듈도 설치하고  passport.initialize와 passport.session 가 적용되었습니다. 
  • const passport = require("passport");
    const passportConfig = require("./passport");
    app.use(
    session({
    secret: process.env.SECRET_CODE,
    resave: false,
    saveUninitialized: true,
    cookie: {
    secure: true,
    httpOnly: true,
    },
    })
    );

    app.use(passport.initialize());
    app.use(passport.session());



    // routing 하기
    app.use(express.static(path.join(__dirname, "public")));

    const pageRouter = require("./routes/page");
    const authRouter = require("./routes/auth");

    app.use("/", pageRouter);

    app.use("/auth", authRouter);

0

김영돈님의 프로필 이미지
김영돈
질문자

프론트에서 withCredentials: true  넣으라는 말씀은 어디에 넣어야 하나요? app.js에 넣는 것인가요? 제가 아직 cors라는 건 아직 진도를 안 나갔고..지금은 deserializer이해하기 하는 중인데요. 좀 막막해서 다시 여쭤봅니다.

김영돈님의 프로필 이미지
김영돈

작성한 질문수

질문하기