인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

지니님의 프로필 이미지
지니

작성한 질문수

[리뉴얼] React로 NodeBird SNS 만들기

쿠키/세션과 전체 로그인 흐름.

로그아웃시 regenerate 에러

작성

·

839

0

제로초님, 최근 req.logout()안에 콜백함수 넣어줘야한다고 공지하신거 봐서 그렇게 진행했는데,

req.session.regenerate(function(err) {

^

TypeError: Cannot read properties of undefined (reading 'regenerate')

이라는 에러가 나고 있습니다. 아래는 제 메인 app.js 설정입니다.

현재 로그아웃은 정상적으로 되고 있으나, dev tool의 네트워크 탭에 로그아웃 버튼 클릭시 post요청은 들어오지 않고, 리덕스의 로그아웃 석세스 이후로는 어떤 서버 요청도 다 실패로 나옵니다. (net::ERR_CONNECTION_REFUSED)

조언부탁드립니다.

const express = require("express");
const session = require("express-session");

const cors = require("cors");
const passport = require("passport");
const cookieParse = require("cookie-parser");
const dotenv = require("dotenv");

const postRouter = require("./routes/post");
const userRouter = require("./routes/user");
const db = require("./models");
const passportConfig = require("./passport");

dotenv.config();
const app = express();
db.sequelize
  .sync()
  .then(() => {
    console.log("db Connected");
  })
  .catch(console.error);

passportConfig();

app.use(cors({ origin: "http://localhost:3000", credentials: true }));
app.use(express.json());
app.use(cookieParse(process.env.COOKIE_SECRET));
app.use(express.urlencoded({ extended: true })); //form data
app.use(
  session({
    saveUninitialized: false,
    resave: false,
    secret: process.env.COOKIE_SECRET,
  })
);
app.use(passport.initialize());
app.use(passport.session());

app.use("/post", postRouter);
app.use("/user", userRouter);

app.listen(3065, () => {
  console.log("Running server");
});

<라우터 설정>

const express = require("express");
const router = express.Router();
const bcrypt = require("bcrypt");
const { User } = require("../models");
const passport = require("passport");

router.post("/login", (req, res, next) => {
  passport.authenticate("local", (err, user, info) => {
    if (err) {
      console.error(err);
      return next(err);
      //To use next, this form is how to extend middleware
    }
    if (info) {
      return res.status(401).send(info.reason);
    }
    return req.login(user, async (loginErr) => {
      if (loginErr) {
        console.error(loginErr);
        return next(loginErr);
      }
      return res.status(201).json(user);
      //Final use info to be passed to front server
    });
  })(req, res, next);
});

router.post("/logout", (req, res) => {
  req.logout(() => {
    res.redirect("/");
  });
  req.session.destroy();
  res.send("ok");
});

router.post("/", async (req, res, next) => {
  try {
    //email existence check
    const exUser = await User.findOne({
      where: {
        email: req.body.email,
      },
    });
    if (exUser) {
      return res.status(403).send("The email is in use");
    }
    const hashedPassword = await bcrypt.hash(req.body.password, 10);
    await User.create({
      //inserting data to table asynchronously
      email: req.body.email,
      nickname: req.body.nickname,
      password: hashedPassword,
    });
    res.status(200).send("ok");
  } catch (error) {
    console.error(error);
    next(error);
  }
});

module.exports = router;

답변 1

1

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

req.session.destroy() 랑 res.send('ok') 지우세요. redirect랑 send랑 같이 못 씁니다.

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

해결됐습니다. 감사합니다~

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

죄송하지만, 해결이 100%된 건 아닌듯 합니다. :(

에러는 없어졌습니다만, 여전히 network 탭에 로그아웃의 post요청은 들어오지 않고 있습니다.

콘솔로그 3개를 아래와 같이 찍어봤을때 watchLogOut 안의 콘솔로그만 찍히지 않네요.

saga의 API주소와 router의 주소를 정확히 일치시켜줬는데 왜 이런지 모르겠네요. 같은 경로에 있는 로그인은 정상작동합니다.

<로그아웃 Saga>

function logOutAPI() {
  console.log("logout1"); <=출력됨
  return axios.post("/user/logout");
}

function* logOut() {
  try {
    console.log("logout2"); <=출력됨
    yield call(logOutAPI);
    yield put({
      type: LOG_OUT_SUCCESS,
    });
  } catch (err) {
    console.error(err);
    yield put({
      type: LOG_OUT_FAILURE,
      error: err.response.data,
    });
  }
}
function* watchLogOut() {
  console.log("logout3"); <=출력 안됨
  yield takeLatest(LOG_OUT_REQUEST, logOut);
}
export default function* userSaga() {
  yield all(
    fork(watchLogOut),
  ]);
}

<로그아웃 관련 라우터>

router.post("/logout", (req, res, next) => {
   req.logout((err) => {
    if (err) {
      console.error(err);
      return next(err);
    } else {
      res.redirect("/user/");
    }
  });
});
제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

지금 보니 axios로 post(ajax요청)을 했으므로 res.send('ok')를 하셔야합니다. res.redirect는 ajax에서 쓰는 이유가 없어집니다. logout3는 페이지 로딩 시 이미 찍혀있을겁니다.

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

빠른 답변 정말 감사드립니다~ 해결했습니다. :)

지니님의 프로필 이미지
지니

작성한 질문수

질문하기